]> git.sesse.net Git - vlc/blobdiff - include/vlc_threads.h
decoder: fix data race in input_DecoderFrameNext()
[vlc] / include / vlc_threads.h
index 0ae5252e1df305e95e8db5c7014c27d3d660c575..d3f021bb40b1a1bda32fa79aabc3066139f161f2 100644 (file)
@@ -34,7 +34,7 @@
  *
  */
 
-#if defined (WIN32)
+#if defined (_WIN32)
 # include <process.h>
 # ifndef ETIMEDOUT
 #  define ETIMEDOUT 10060 /* This is the value in winsock.h. */
@@ -155,8 +155,12 @@ typedef struct vlc_timer *vlc_timer_t;
 typedef pthread_t       vlc_thread_t;
 typedef pthread_mutex_t vlc_mutex_t;
 #define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
-typedef pthread_cond_t  vlc_cond_t;
-#define VLC_STATIC_COND  PTHREAD_COND_INITIALIZER
+typedef struct
+{
+    pthread_cond_t cond;
+    unsigned clock;
+} vlc_cond_t;
+#define VLC_STATIC_COND  { PTHREAD_COND_INITIALIZER, 0 }
 typedef semaphore_t     vlc_sem_t;
 typedef pthread_rwlock_t vlc_rwlock_t;
 #define VLC_STATIC_RWLOCK PTHREAD_RWLOCK_INITIALIZER
@@ -382,108 +386,58 @@ struct vlc_cleanup_t
         vlc_cleanup_data.proc (vlc_cleanup_data.data); \
     } while (0)
 
-#endif /* !LIBVLC_USE_PTHREAD_CLEANUO */
+#endif /* !LIBVLC_USE_PTHREAD_CLEANUP */
 
 #ifndef LIBVLC_USE_PTHREAD_CANCEL
 /* poll() with cancellation */
+# ifdef __OS2__
 static inline int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
 {
-    vlc_testcancel ();
+    static int (*vlc_poll_os2)(struct pollfd *, unsigned, int) = NULL;
 
-    while (timeout > 50)
+    if (!vlc_poll_os2)
     {
-        int val = poll (fds, nfds, timeout);
-        if (val != 0)
-            return val;
-        timeout -= 50;
-        vlc_testcancel ();
-    }
+        HMODULE hmod;
+        CHAR szFailed[CCHMAXPATH];
 
-    return poll (fds, nfds, timeout);
-}
-# define poll(u,n,t) vlc_poll(u, n, t)
+        if (DosLoadModule(szFailed, sizeof(szFailed), "vlccore", &hmod))
+            return -1;
 
-#endif /* LIBVLC_USE_PTHREAD_CANCEL */
-
-static inline void vlc_cleanup_lock (void *lock)
-{
-    vlc_mutex_unlock ((vlc_mutex_t *)lock);
-}
-#define mutex_cleanup_push( lock ) vlc_cleanup_push (vlc_cleanup_lock, lock)
-
-#if defined (_POSIX_SPIN_LOCKS) && ((_POSIX_SPIN_LOCKS - 0) > 0)
-typedef pthread_spinlock_t vlc_spinlock_t;
-
-/**
- * Initializes a spinlock.
- */
-static inline void vlc_spin_init (vlc_spinlock_t *spin)
-{
-    if (pthread_spin_init (spin, PTHREAD_PROCESS_PRIVATE))
-        abort ();
-}
-
-/**
- * Acquires a spinlock.
- */
-static inline void vlc_spin_lock (vlc_spinlock_t *spin)
-{
-    pthread_spin_lock (spin);
-}
+        if (DosQueryProcAddr(hmod, 0, "_vlc_poll_os2", (PFN *)&vlc_poll_os2))
+            return -1;
+    }
 
-/**
- * Releases a spinlock.
- */
-static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
-{
-    pthread_spin_unlock (spin);
+    return (*vlc_poll_os2)(fds, nfds, timeout);
 }
-
-/**
- * Deinitializes a spinlock.
- */
-static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
+# else
+static inline int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
 {
-    pthread_spin_destroy (spin);
-}
-
-#elif defined (WIN32)
-typedef CRITICAL_SECTION vlc_spinlock_t;
+    int val;
 
-static inline void vlc_spin_init (vlc_spinlock_t *spin)
-{
-    if (!InitializeCriticalSectionAndSpinCount(spin, 4000))
-        abort ();
-}
+    do
+    {
+        int ugly_timeout = ((unsigned)timeout >= 50) ? 50 : timeout;
+        if (timeout >= 0)
+            timeout -= ugly_timeout;
 
-static inline void vlc_spin_lock (vlc_spinlock_t *spin)
-{
-    EnterCriticalSection(spin);
-}
+        vlc_testcancel ();
+        val = poll (fds, nfds, ugly_timeout);
+    }
+    while (val == 0 && timeout != 0);
 
-static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
-{
-    LeaveCriticalSection(spin);
+    return val;
 }
+# endif
 
-static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
-{
-    DeleteCriticalSection(spin);
-}
+# define poll(u,n,t) vlc_poll(u, n, t)
 
-#else
-/* Fallback to plain mutexes if spinlocks are not available */
-typedef vlc_mutex_t vlc_spinlock_t;
+#endif /* LIBVLC_USE_PTHREAD_CANCEL */
 
-static inline void vlc_spin_init (vlc_spinlock_t *spin)
+static inline void vlc_cleanup_lock (void *lock)
 {
-    vlc_mutex_init (spin);
+    vlc_mutex_unlock ((vlc_mutex_t *)lock);
 }
-
-# define vlc_spin_lock    vlc_mutex_lock
-# define vlc_spin_unlock  vlc_mutex_unlock
-# define vlc_spin_destroy vlc_mutex_destroy
-#endif
+#define mutex_cleanup_push( lock ) vlc_cleanup_push (vlc_cleanup_lock, lock)
 
 #ifdef __cplusplus
 /**