$OpenBSD: patch-plugin_icedteanp_IcedTeaPluginRequestProcessor_cc,v 1.1 2012/03/29 12:28:27 kurt Exp $
--- plugin/icedteanp/IcedTeaPluginRequestProcessor.cc.orig	Wed Mar 28 15:02:26 2012
+++ plugin/icedteanp/IcedTeaPluginRequestProcessor.cc	Wed Mar 28 15:24:27 2012
@@ -50,6 +50,7 @@ exception statement from your version. */
 // Initialize static members used by the queue processing framework
 pthread_mutex_t message_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t syn_write_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t cond_message_available = PTHREAD_COND_INITIALIZER;
 std::vector< std::vector<std::string*>* >* message_queue = new std::vector< std::vector<std::string*>* >();
 
 /**
@@ -64,10 +65,16 @@ PluginRequestProcessor::PluginRequestProcessor()
 
     internal_req_ref_counter = 0;
 
+#if 0
+// These global mutexes and condition variables are staticly initialized.
+// If more then one instance of this class is created, the second one will
+// reinit the global variables that the first is using. There is no need
+// to reinit them as they were initialized with the static initializer.
     pthread_mutex_init(&message_queue_mutex, NULL);
     pthread_mutex_init(&syn_write_mutex, NULL);
 
     pthread_cond_init(&cond_message_available, NULL);
+#endif 
 }
 
 /**
@@ -83,10 +90,15 @@ PluginRequestProcessor::~PluginRequestProcessor()
     if (pendingRequests)
         delete pendingRequests;
 
+#if 0
+// If more then one instance of this class is created, the second one will
+// destroy the global variables that the first instance is using. There is
+// no need to destroy the global mutexes. They can be safely reused.
     pthread_mutex_destroy(&message_queue_mutex);
     pthread_mutex_destroy(&syn_write_mutex);
 
     pthread_cond_destroy(&cond_message_available);
+#endif
 }
 
 /**
@@ -142,11 +154,14 @@ PluginRequestProcessor::newMessageOnBus(const char* me
             // Update queue synchronously
             pthread_mutex_lock(&message_queue_mutex);
             message_queue->push_back(message_parts);
-            pthread_mutex_unlock(&message_queue_mutex);
-
             // Broadcast that a message is now available
+            // NOTE: to avoid lost wakeups pthread_cond_broadcast and
+            // pthread_cond_signal must be called while holding
+            // the associated mutex locked
             pthread_cond_broadcast(&cond_message_available);
+            pthread_mutex_unlock(&message_queue_mutex);
 
+
             return true;
         }
 
@@ -635,9 +650,6 @@ PluginRequestProcessor::loadURL(std::vector<std::strin
 static void
 queue_cleanup(void* data)
 {
-
-    pthread_mutex_destroy((pthread_mutex_t*) data);
-
     PLUGIN_DEBUG("Queue processing stopped.\n");
 }
 
@@ -648,14 +660,11 @@ queue_processor(void* data)
     PluginRequestProcessor* processor = (PluginRequestProcessor*) data;
     std::vector<std::string*>* message_parts = NULL;
     std::string command;
-    pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER;
 
     PLUGIN_DEBUG("Queue processor initialized. Queue = %p\n", message_queue);
 
-    pthread_mutex_init(&wait_mutex, NULL);
+    pthread_cleanup_push(queue_cleanup, NULL);
 
-    pthread_cleanup_push(queue_cleanup, (void*) &wait_mutex);
-
     while (true)
     {
         pthread_mutex_lock(&message_queue_mutex);
@@ -723,9 +732,12 @@ queue_processor(void* data)
 
         } else
         {
-	    pthread_mutex_lock(&wait_mutex);
-	    pthread_cond_wait(&cond_message_available, &wait_mutex);
-	    pthread_mutex_unlock(&wait_mutex);
+	    pthread_mutex_lock(&message_queue_mutex);
+            if (message_queue->size() == 0)
+            {
+	        pthread_cond_wait(&cond_message_available, &message_queue_mutex);
+            }
+	    pthread_mutex_unlock(&message_queue_mutex);
         }
 
         message_parts = NULL;
