1 /* EINA - EFL data type library
2  * Copyright (C) 2011 Vincent Torri
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef EINA_LOCK_H_
20 #define EINA_LOCK_H_
21 
22 #include "eina_config.h"
23 #include "eina_types.h"
24 #include "eina_error.h"
25 #include "eina_main.h"
26 
27 /**
28  * @defgroup Eina_Lock_Group Lock
29  * @ingroup Eina_Tools_Group
30  * @brief This group provides thread locking and synchronization capabilities.
31  *
32  * Similar to POSIX threads (pthreads), but it takes care of the platform specific
33  * details so you don't have to.
34  *
35  * If you know how @c pthreads work, this library will look familiar to you.
36  * If you are not familiar with @c pthreads, a good overview is available
37  * <a href="https://computing.llnl.gov/tutorials/pthreads/">here</a>
38  *
39  * The Eina lock functions are grouped into several categories to handle different
40  * thread locking and synchronization methods:
41  * @li eina_lock_* - Functions that implement locking.
42  * @li eina_condition_* - Functions that implement condition variables.
43  * @li eina_rwlock_* - Functions that implement read/write locks.
44  * @li eina_tls_* - Functions that implement thread level storage.
45  * @li eina_semaphore_* - Functions that implement semaphores.
46  * @li eina_barrier_* - Functions that implement barriers.
47  * @li eina_spinlock_* - Functions that implement spinlocks if they are available
48  * on the platform.  If they are not available, these functions degrade to plain locks.
49  *
50  *
51  *
52  * @{
53  */
54 
55 /**
56 * @typedef Eina_Barrier
57 * @brief An opaque type for working with barrier locks.
58 */
59 /**
60 * @typedef Eina_Lock
61 * @brief An opaque type for working with locks.
62 */
63 /**
64 * @typedef Eina_Condition
65 * @brief An opaque type that represents a condition variable.
66 */
67 /**
68 * @typedef Eina_RWLock
69 * @brief An opaque type for working with read/write locks.
70 */
71 /**
72 * @typedef Eina_TLS
73 * @brief An opaque type for working with thread level storage.
74 */
75 /**
76 * @typedef Eina_Semaphore
77 * @brief An opaque type for working with semaphores.
78 */
79 /**
80 * @typedef Eina_Spinlock
81 * @brief An opaque type for working with spinlocks.
82 */
83 
84 /**
85  * @typedef Eina_Lock_Result
86  * @brief Return codes for lock operations.
87  */
88 typedef enum
89 {
90    EINA_LOCK_FAIL     = EINA_FALSE, /**< Indicates that the lock operation failed. */
91    EINA_LOCK_SUCCEED  = EINA_TRUE,  /**< Indicates that the lock operation succeeded. */
92    EINA_LOCK_DEADLOCK               /**< Indicates that the lock is deadlocked. */
93 } Eina_Lock_Result;
94 
95 /**
96  * @brief A callback type for deallocation of thread level storage data.
97  */
98 typedef void (*Eina_TLS_Delete_Cb)(void *ptr);
99 
100 #include "eina_inline_lock_posix.x"
101 
102 /**
103  * @brief A type definition for warning that a function was called from
104  *        somewhere other than the EFL main loop.
105  */
106 EAPI extern Eina_Error EINA_ERROR_NOT_MAIN_LOOP;
107 
108 /**
109  * @brief Initializes a new #Eina_Lock.
110  *
111  * @param[in] mutex The #Eina_Lock structure to be initialized
112  * @return #EINA_TRUE on success, #EINA_FALSE otherwise
113  *
114  * @details This function initializes an #Eina_Lock with appropriate values.
115  *          These values are platform dependent as is the structure of the
116  *          #Eina_Lock itself.
117  *
118  * @see eina_lock_free()
119  */
120 static inline Eina_Bool eina_lock_new(Eina_Lock *mutex);
121 
122 /**
123  * @brief Initializes a new #Eina_Lock that is recursive.
124  *
125  * @param[in] mutex The #Eina_Lock structure to be initialized
126  * @return #EINA_TRUE on success, #EINA_FALSE otherwise
127  *
128  * @details This function initializes an #Eina_Lock with appropriate values.
129  *          These values are platform dependent as is the structure of the
130  *          #Eina_Lock itself.
131  *
132  * @see eina_lock_new()
133  * @see eina_lock_free()
134  * @since 1.19
135  */
136 static inline Eina_Bool eina_lock_recursive_new(Eina_Lock *mutex);
137 
138 /**
139  * @brief Deallocates an #Eina_Lock.
140  * @details This function deallocates an #Eina_Lock allocated by eina_lock_new()
141  *          and does any platform dependent cleanup that is required.
142  *
143  * @param[in] mutex The #Eina_Lock structure to be deallocated
144  *
145  * @see eina_lock_new()
146  */
147 static inline void eina_lock_free(Eina_Lock *mutex);
148 
149 /**
150  * @brief Attempts to take a lock.
151  * @details This function attempts to gain a lock on the indicated #Eina_Lock. If the
152  *          underlying #Eina_Lock is locked already, this call can be blocked until
153  *          the lock is released. This is appropriate in many cases, but consider using
154  *          eina_lock_take_try() if you don't need to block.
155  *
156  * @param[in] mutex The #Eina_Lock to take
157  *
158  * @return Returns #EINA_LOCK_SUCCEED on success. If the operation fails because
159  *         a deadlock condition exists, it returns #EINA_LOCK_DEADLOCK. If some other
160  *         condition causes the take to fail, #EINA_LOCK_FAIL is returned.
161  *
162  * @see eina_lock_take_try()
163  * @see eina_lock_release()
164  */
165 static inline Eina_Lock_Result eina_lock_take(Eina_Lock *mutex);
166 
167 /**
168  * @brief Attempts to take a lock if possible.
169  * @details This function attempts to gain a lock on the indicated #Eina_Lock.
170             Identical eina_lock_take(), but returns immediately if the lock is already taken.
171  *
172  * @param[in] mutex The #Eina_Lock to take
173  *
174  * @return Returns #EINA_LOCK_SUCCEED on success. If the operation fails because
175  *         a deadlock condition exists, it returns #EINA_LOCK_DEADLOCK. If some other
176  *         condition causes the take to fail, #EINA_LOCK_FAIL is returned.
177  *
178  * @see eina_lock_take()
179  * @see eina_lock_release()
180  */
181 static inline Eina_Lock_Result eina_lock_take_try(Eina_Lock *mutex);
182 
183 /**
184  * @brief Releases a lock.
185  * @details This function releases the lock on the indicated #Eina_Lock. If successful,
186  *          and @c EINA_HAVE_DEBUG_THREADS is defined, @p mutex is updated and information
187  *          about the locking process is removed (e.g. thread number and backtrace for POSIX).
188  *
189  * @param[in] mutex The #Eina_Lock to release
190  *
191  * @return Returns #EINA_LOCK_SUCCEED on success,  If it fails, #EINA_LOCK_FAIL is
192  *         returned.
193  *
194  * @see eina_lock_take()
195  * @see eina_lock_take_try()
196  */
197 static inline Eina_Lock_Result eina_lock_release(Eina_Lock *mutex);
198 
199 /**
200  * @brief Prints debug information about a lock.
201  * @details This function prints debug information for @p mutex.  The information is
202  *          platform dependent.  On POSIX systems it prints the address of @p mutex,
203  *          lock state, thread number and a backtrace.
204  *
205  * @param[in] mutex The #Eina_Lock to print debug info for.
206  *
207  * @note If @c EINA_HAVE_DEBUG_THREADS is not defined, this function does nothing.
208  *
209  * @since 1.19
210  */
211 EAPI void eina_lock_debug(const Eina_Lock *mutex);
212 
213 /**
214  * @brief Initializes a new condition variable.
215  * @details This function initializes an #Eina_Condition structure and associates it with
216  *          an existing lock.
217  *
218  * @param[in] cond The condition variable to create
219  * @param[in] mutex The #Eina_Lock structure that controls access to this condition variable
220  *
221  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
222  *
223  * Condition variables are used to coordinate actions between threads.  See
224  * <a href="https://computing.llnl.gov/tutorials/pthreads/#ConVarOverview"> Condition Variable Overview </a>
225  * for an introduction to condition variables and their use.
226  *
227  * @see eina_condition_free()
228  */
229 static inline Eina_Bool eina_condition_new(Eina_Condition *cond, Eina_Lock *mutex);
230 
231 /**
232  * @brief Deallocates a condition variable.
233  * @details This function deallocates a condition variable and does any platform dependent
234  *          cleanup that is required.
235  *
236  * @param[in] cond The condition variable to be deallocated.
237  *
238  * @see eina_condition_new()
239  */
240 static inline void eina_condition_free(Eina_Condition *cond);
241 
242 /**
243  * @brief Causes a thread to wait until signaled by the condition.
244  * @details This function makes a thread block until a signal is sent to it via @p cond.
245  *
246  * @param[in] cond The #Eina_Condition upon which the thread waits.
247  *
248  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
249  *
250  * @see eina_condition_timedwait()
251  */
252 static inline Eina_Bool eina_condition_wait(Eina_Condition *cond);
253 
254 /**
255  * @brief Causes a thread to wait until signaled by the condition or a
256  *        timeout is reached.
257  * @details This function makes a thread block until either a signal is sent to it via
258  *          @p cond or @p t seconds have passed.
259  *
260  * @param[in] cond The #Eina_Condition upon which the thread waits.
261  * @param[in] t The maximum amount of time to wait, in seconds.
262  *
263  * @return #EINA_TRUE on success, #EINA_FALSE otherwise. If the operation
264  *         timed out, eina error will be set to @c ETIMEDOUT.
265  *
266  * @see eina_condition_wait()
267  */
268 static inline Eina_Bool eina_condition_timedwait(Eina_Condition *cond, double t);
269 
270 /**
271  * @brief Signals all threads waiting for a condition.
272  * @details This function sends a signal to all the threads waiting on the condition @p cond.
273  *          If you know for sure that there is only one thread waiting, use eina_condition_signal()
274  *          instead to gain a little optimization.
275  *
276  * @param[in] cond The #Eina_Condition that signals all its waiting threads.
277  *
278  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
279  *
280  * @see eina_condition_signal()
281  */
282 static inline Eina_Bool eina_condition_broadcast(Eina_Condition *cond);
283 
284 /**
285  * @brief Signals a thread waiting for a condition.
286  * @details This function sends a signal to a thread waiting on the condition @p cond.
287  *          If you do not know for sure that there is only one thread waiting, use
288  *          eina_condition_broadcast() instead.
289  *
290  * @param[in] cond The #Eina_Condition that signals its waiting thread.
291  *
292  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
293  *
294  * @note If there is more than one thread waiting on this condition, one of them is
295  *       signaled, but which one is undefined.
296  *
297  * @see eina_condition_broadcast()
298  */
299 static inline Eina_Bool eina_condition_signal(Eina_Condition *cond);
300 
301 
302 /**
303  * @brief Initializes a new #Eina_RWLock.
304  * @details This function initializes an #Eina_RWLock with appropriate values.
305  *          These values are platform dependent as is the structure of the #Eina_RWLock
306  *          itself.
307  *
308  * @param[in] mutex The #Eina_RWLock to be initialized.
309  *
310  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
311  *
312  * @see eina_rwlock_free()
313  */
314 static inline Eina_Bool eina_rwlock_new(Eina_RWLock *mutex);
315 
316 /**
317  * @brief Deallocates an #Eina_RWLock.
318  * @details This function deallocates an #Eina_RWLock and does any platform dependent
319  *          cleanup that is required.
320  *
321  * @param[in] mutex The #Eina_RWLock structure to be deallocated.
322  *
323  * @see eina_rwlock_new()
324  */
325 static inline void eina_rwlock_free(Eina_RWLock *mutex);
326 
327 /**
328  * @brief Attempts to take a read lock.
329  * @details This function attempts to gain a read lock on the indicated #Eina_RWLock. If
330  *          the #Eina_RWLock is write locked, this call can be blocked until
331  *          the lock is released.
332  *
333  * @param[in] mutex The #Eina_RWLock to take.
334  *
335  * @return Returns #EINA_LOCK_SUCCEED on success, #EINA_LOCK_FAIL on failure.
336  *
337  * @note This function never returns #EINA_LOCK_DEADLOCK.
338  *
339  * @see eina_rwlock_release()
340  */
341 static inline Eina_Lock_Result eina_rwlock_take_read(Eina_RWLock *mutex);
342 
343 /**
344  * @brief Attempts to take a write lock.
345  * @details This function attempts to gain a write lock on the indicated #Eina_RWLock. If
346  *          the #Eina_RWLock is locked for reading or writing, this call can be
347  *          blocked until the lock is released.
348  *
349  * @param[in] mutex The #Eina_RWLock to take.
350  *
351  * @return Returns #EINA_LOCK_SUCCEED on success, #EINA_LOCK_FAIL on failure.
352  *
353  * @note This function never returns #EINA_LOCK_DEADLOCK.
354  *
355  * @see eina_rwlock_release()
356  */
357 static inline Eina_Lock_Result eina_rwlock_take_write(Eina_RWLock *mutex);
358 
359 /**
360  * @brief Releases a lock.
361  * @details This function releases the lock on the indicated #Eina_RWLock.
362  *
363  * @param[in] mutex The #Eina_RWLock to release.
364  *
365  * @return Returns #EINA_LOCK_SUCCEED on success.  If it fails, #EINA_LOCK_FAIL is
366  *         returned.
367  *
368  * @see eina_rwlock_take_read()
369  * @see eina_rwlock_take_write()
370  */
371 static inline Eina_Lock_Result eina_rwlock_release(Eina_RWLock *mutex);
372 
373 /**
374  * @brief Initializes a new #Eina_TLS, or thread level storage, to store thread
375  *        specific data.
376  * @details This function initializes an #Eina_TLS with @p key but does not set a
377  *          callback to deallocate @p key when the thread exits. The implementation
378  *          is platform dependent as is the structure of the #Eina_TLS itself.
379  *
380  * @param[in] key The #Eina_TLS to be initialized.
381  *
382  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
383  *
384  * @note use eina_tls_cb_new() instead to set a callback for deallocating @p key.
385  *
386  * @see eina_tls_cb_new()
387  * @see eina_tls_free()
388  */
389 static inline Eina_Bool eina_tls_new(Eina_TLS *key);
390 
391 /**
392  * @brief Initializes a new #Eina_TLS, or thread level storage, to store thread
393  *        specific data.
394  * @details This function initializes an #Eina_TLS with @p key and sets a
395  *          callback to deallocate @p key when the thread exits. The implementation
396  *          is platform dependent as is the structure of the #Eina_TLS itself.
397  *
398  * @param[in] key The #Eina_TLS to be initialized.
399  * @param[in] delete_cb A pointer to a function that deallocates @p key.
400  *
401  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
402  *
403  * @see eina_tls_new()
404  * @see eina_tls_free()
405  */
406 static inline Eina_Bool eina_tls_cb_new(Eina_TLS *key, Eina_TLS_Delete_Cb delete_cb);
407 
408 /**
409  * @brief Frees an allocated #Eina_TLS.
410  * @details This function frees the #Eina_TLS @p key. The implementation
411  *          is platform dependent.
412  *
413  * @param[in] key The #Eina_TLS to be freed.
414  *
415  * @see eina_tls_new()
416  * @see eina_tls_cb_new()
417  */
418 static inline void eina_tls_free(Eina_TLS key);
419 
420 /**
421  * @brief Gets the value in #Eina_TLS for this thread.
422  * @details This function gets a pointer to the data associated with #Eina_TLS @p key for
423  *          this thread. The implementation is platform dependent.
424  *
425  * @param[in] key The #Eina_TLS to be retrieved.
426  *
427  * @return A pointer to the data associated with @p key.
428  *
429  * @see  eina_tls_set()
430  */
431 static inline void *eina_tls_get(Eina_TLS key);
432 
433 /**
434  * @brief Sets the value in Eina_TLS for this thread.
435  * @details This function sets the value associated with @p key to the pointer to the data
436  *          @p data. The implementation is platform dependent.
437  *
438  * @param[in] key The #Eina_TLS to be set.
439  * @param[in] data A pointer to the data to be stored.
440  *
441  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
442  *
443  * @see eina_tls_get()
444  */
445 static inline Eina_Bool eina_tls_set(Eina_TLS key, const void *data);
446 
447 /**
448  * @brief Initializes a new #Eina_Semaphore.
449  * @details This function initializes an unnamed #Eina_Semaphore with appropriate values.
450  *          These values are platform dependent.
451  *
452  * @param[in] sem The #Eina_Semaphore to be initialized.
453  * @param[in] count_init Indicates the initial count of threads waiting on this semaphore.
454  *
455  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
456  *
457  * @see eina_semaphore_free()
458  */
459 static inline Eina_Bool eina_semaphore_new(Eina_Semaphore *sem, int count_init);
460 
461 /**
462  * @brief Frees an allocated #Eina_Semaphore.
463  * @details This function frees the #Eina_Semaphore @p sem. The implementation
464  *          is platform dependent.
465  *
466  * @param[in] sem The #Eina_Semaphore to be freed.
467  *
468  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
469  *
470  * @see eina_semaphore_new()
471  */
472 static inline Eina_Bool eina_semaphore_free(Eina_Semaphore *sem);
473 
474 /**
475  * @brief Gets a lock on an #Eina_Semaphore.
476  * @details This function locks the #Eina_Semaphore @p sem. The implementation
477  *          is platform dependent.
478  *
479  * @param[in] sem The #Eina_Semaphore to lock.
480  *
481  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
482  *
483  * @see eina_semaphore_release()
484  */
485 static inline Eina_Bool eina_semaphore_lock(Eina_Semaphore *sem);
486 
487 /**
488  * @brief Releases a lock on an #Eina_Semaphore.
489  * @details This function releases a lock on the #Eina_Semaphore @p sem. The implementation
490  *          is platform dependent.
491  *
492  * @param[in] sem The #Eina_Semaphore to release.
493  * @param[in] count_release Not used.
494  *
495  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
496  *
497  * @see eina_semaphore_lock()
498  */
499 static inline Eina_Bool eina_semaphore_release(Eina_Semaphore *sem, int count_release);
500 
501 /**
502  * @brief Initializes a new #Eina_Barrier.
503  * @details This function initializes a new #Eina_Barrier.  It sets the @c needed flag
504  *          to the value of @p needed, sets the barrier's @c count member to 0 and
505  *          creates new #Eina_Lock and #Eina_Condition objects for the barrier.
506  *
507  * @param[in] barrier The #Eina_Barrier to be initialized.
508  * @param[in] needed The number of thread waits that causes this barrier to be reset.
509  *
510  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
511  *
512  * @see eina_barrier_free()
513  */
514 static inline Eina_Bool eina_barrier_new(Eina_Barrier *barrier, int needed);
515 
516 /**
517  * @brief Frees an allocated #Eina_Barrier.
518  * @details This function frees the #Eina_Barrier @p barrier.
519  *
520  * @param[in] barrier The #Eina_Barrier to be freed.
521  *
522  * @see eina_barrier_new()
523  */
524 static inline void eina_barrier_free(Eina_Barrier *barrier);
525 
526 /**
527  * @brief Increments the count of threads that are waiting on @p barrier.
528  * @details When the count of threads reaches the @c needed value for the barrier, all
529  *          waiting threads are notified via eina_condition_broadcast().
530  * @param[in] barrier The #Eina_Barrier to be incremented.
531  *
532  * @return #EINA_TRUE on success, else #EINA_FALSE otherwise.
533  *
534  */
535 static inline Eina_Bool eina_barrier_wait(Eina_Barrier *barrier);
536 
537 
538 /**
539  * @brief Initializes a new #Eina_Spinlock.
540  * @details This function initializes a new #Eina_Spinlock, if spinlocks are available. If
541  *          spinlocks are not available, it creates a new #Eina_Lock.
542  *
543  * @param[in] spinlock The #Eina_Spinlock to be initialized.
544  *
545  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
546  *
547  * @note Spinlocks are only implemented on the POSIX platform and are only available
548  *      if @c EINA_HAVE_POSIX_SPINLOCK is defined. You get a new #Eina_Lock on All other platforms.
549  *
550  * @see eina_spinlock_free()
551  */
552 static inline Eina_Bool eina_spinlock_new(Eina_Spinlock *spinlock);
553 
554 /**
555  * @brief Attempts to take a spinlock.
556  * @details This function attempts to gain a lock on the indicated #Eina_Spinlock. If the
557  *          underlying #Eina_Spinlock is locked already, this call can be blocked until
558  *          the lock is released. This is appropriate in many cases, but consider using
559  *          eina_spinlock_take_try() if you don't need to block.
560  *
561  * @param[in] spinlock The #Eina_Spinlock to take.
562  *
563  * @return Returns #EINA_LOCK_SUCCEED on success.  If the operation fails because
564  *         a deadlock condition exists, it returns #EINA_LOCK_DEADLOCK. If some other
565  *         condition causes the take to fail, #EINA_LOCK_FAIL is returned.
566  *
567  * @see eina_spinlock_take_try()
568  * @see eina_spinlock_release()
569  */
570 static inline Eina_Lock_Result eina_spinlock_take(Eina_Spinlock *spinlock);
571 
572 /**
573  * @brief Attempts to take a spinlock if possible.
574  * @details This function attempts to gain a lock on the indicated #Eina_Spinlock. Identical
575  *          to eina_lock_take(), but returns immediately if the lock is already taken.
576  *
577  * @param[in] spinlock The #Eina_Spinlock to take.
578  *
579  * @return Returns #EINA_LOCK_SUCCEED on success. If the operation fails because
580  *         a deadlock condition exists, it returns #EINA_LOCK_DEADLOCK. If some other
581  *         condition causes the take to fail, #EINA_LOCK_FAIL is returned.
582  *
583  * @see eina_spinlock_take_try()
584  * @see eina_spinlock_release()
585  */
586 static inline Eina_Lock_Result eina_spinlock_take_try(Eina_Spinlock *spinlock);
587 
588 /**
589  * @brief Releases a spinlock.
590  * @details This function will release the lock on the indicated #Eina_Spinlock. If successful,
591  *          and @c EINA_HAVE_DEBUG_THREADS is defined, @p mutex is updated and information
592  *          about the locking process is removed (e.g. thread number and backtrace for POSIX).
593  *
594  * @param[in] spinlock The #Eina_Spinlock to release.
595  *
596  * @return Returns #EINA_LOCK_SUCCEED on success, #EINA_LOCK_FAIL otherwise.
597  *
598  * @see eina_spinlock_take()
599  * @see eina_spinlock_take_try()
600 
601  */
602 static inline Eina_Lock_Result eina_spinlock_release(Eina_Spinlock *spinlock);
603 
604 /**
605  * @brief Deallocates an #Eina_Spinlock.
606  * @details This function deallocates an #Eina_Spinlock and does any platform dependent
607  *          cleanup that is required.
608  *
609  * @param[in] spinlock The #Eina_Spinlock to be deallocated.
610  *
611  */
612 static inline void eina_spinlock_free(Eina_Spinlock *spinlock);
613 
614 #ifdef EINA_HAVE_DEBUG_THREADS
615 # define EINA_MAIN_LOOP_CHECK_RETURN_VAL(val)				\
616   do {									\
617     if (EINA_UNLIKELY(!eina_main_loop_is()))				\
618       {									\
619 	EINA_LOG_ERR("You are calling %s from outside"			\
620 		     "of the main loop threads in %s at line %i",	\
621 		     __func__,					\
622 		     __FILE__,						\
623 		     __LINE__);						\
624 	return val;							\
625       }									\
626   } while (0)
627 # define EINA_MAIN_LOOP_CHECK_RETURN					\
628   do {									\
629     if (EINA_UNLIKELY(!eina_main_loop_is()))				\
630       {									\
631 	EINA_LOG_ERR("You are calling %s from outside"			\
632 		     "of the main loop threads in %s at line %i",	\
633 		     __func__,					\
634 		     __FILE__,						\
635 		     __LINE__);						\
636 	return ;							\
637       }									\
638   } while (0)
639 #else
640 /**
641  * @def EINA_MAIN_LOOP_CHECK_RETURN_VAL
642  * @brief Definition for the macro that doesn't do anything unless @c EINA_HAVE_DEBUG_THREADS is defined.
643  * @param[in] val The value to be returned
644  */
645 # define EINA_MAIN_LOOP_CHECK_RETURN_VAL(val) do {} while(0)
646 /**
647  * @def EINA_MAIN_LOOP_CHECK_RETURN
648  * @brief Definition for the macro that doesn't do anything unless @c EINA_HAVE_DEBUG_THREADS is defined.
649  */
650 # define EINA_MAIN_LOOP_CHECK_RETURN do {} while(0)
651 #endif
652 
653 /**
654  * @}
655  */
656 
657 #endif
658