From d86c01a9d5d6a90f6254ad5cef2d02089af7d2b5 Mon Sep 17 00:00:00 2001
From: Sergey Radionov <RSATom@gmail.com>
Date: Wed, 7 Dec 2011 07:50:21 +0700
Subject: [PATCH 1/1] libavcodec/phtread.c: fixed deadlock under win32

---
 libavcodec/pthread.c |   24 +++++++++++++++---------
 1 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 8aac89f..8cb7d92 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -58,6 +58,7 @@ typedef struct ThreadContext {
     pthread_cond_t last_job_cond;
     pthread_cond_t current_job_cond;
     pthread_mutex_t current_job_lock;
+	int running_threads;
     int current_job;
     int done;
 } ThreadContext;
@@ -139,32 +140,37 @@ static void* attribute_align_arg worker(void *v)
 {
     AVCodecContext *avctx = v;
     ThreadContext *c = avctx->thread_opaque;
-    int our_job = c->job_count;
-    int thread_count = avctx->thread_count;
+    int our_job;
     int self_id;
 
     pthread_mutex_lock(&c->current_job_lock);
-    self_id = c->current_job++;
+    self_id = c->running_threads++;
     for (;;){
-        while (our_job >= c->job_count) {
-            if (c->current_job == thread_count + c->job_count)
+        do {
+            if (!c->job_count)
                 pthread_cond_signal(&c->last_job_cond);
 
             pthread_cond_wait(&c->current_job_cond, &c->current_job_lock);
-            our_job = self_id;
+            if (c->current_job < c->job_count)
+                our_job = (c->current_job)++;
+            else
+                our_job = c->job_count;
 
             if (c->done) {
+                --c->running_threads;
                 pthread_mutex_unlock(&c->current_job_lock);
                 return NULL;
             }
-        }
+        } while (our_job >= c->job_count);
+
         pthread_mutex_unlock(&c->current_job_lock);
 
         c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size):
                                                    c->func2(avctx, c->args, our_job, self_id);
 
         pthread_mutex_lock(&c->current_job_lock);
-        our_job = c->current_job++;
+
+        --c->job_count;
     }
 }
 
@@ -207,7 +213,7 @@ static int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void
 
     pthread_mutex_lock(&c->current_job_lock);
 
-    c->current_job = avctx->thread_count;
+    c->current_job = 0;
     c->job_count = job_count;
     c->job_size = job_size;
     c->args = arg;
-- 
1.7.7.1.msysgit.0

