From f12fa4c36216e83246767a3cff8dbc86e7d7c6eb Mon Sep 17 00:00:00 2001
From: erdgeist <>
Date: Fri, 16 Jan 2009 02:26:50 +0000
Subject: Use a self pipe to wake from io_wait when a thread finished his work.

---
 opentracker.c  | 12 ++++++++++++
 ot_mutex.c     |  7 +++++++
 trackerlogic.h |  2 +-
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/opentracker.c b/opentracker.c
index 970995a..8811a6e 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -38,6 +38,7 @@ time_t       g_now_seconds;
 char *       g_redirecturl = NULL;
 uint32_t     g_tracker_id;
 volatile int g_opentracker_running = 1;
+int          g_self_pipe[2];
 
 static char * g_serverdir = NULL;
 
@@ -216,6 +217,8 @@ static void server_mainloop( ) {
         handle_accept( sock );
       else if( (intptr_t)cookie == FLAG_UDP )
         handle_udp6( sock, &ws );
+      else if( (intptr_t)cookie == FLAG_SELFPIPE ) { printf( "woke up\n" );
+      io_tryread( sock, ws.inbuf, G_INBUF_SIZE ); }
       else
         handle_read( sock, &ws );
     }
@@ -500,6 +503,15 @@ while( scanon ) {
 
   g_now_seconds = time( NULL );
 
+  /* Create our self pipe which allows us to interrupt mainloops
+     io_wait in case some data is available to send out */
+  if( pipe( g_self_pipe ) == -1 )
+    panic( "selfpipe failed: " );
+  if( !io_fd( g_self_pipe[0] ) )
+    panic( "selfpipe io_fd failed: " );
+  io_setcookie( g_self_pipe[0], (void*)FLAG_SELFPIPE );
+  io_wantread( g_self_pipe[0] );
+
   /* Init all sub systems. This call may fail with an exit() */
   trackerlogic_init( );
 
diff --git a/ot_mutex.c b/ot_mutex.c
index 2ed5e81..0127721 100644
--- a/ot_mutex.c
+++ b/ot_mutex.c
@@ -32,6 +32,9 @@ static int bucket_locklist_count = 0;
 static pthread_mutex_t bucket_mutex;
 static pthread_cond_t bucket_being_unlocked;
 
+/* Self pipe from opentracker.c */
+extern int g_self_pipe[2];
+
 static int bucket_check( int bucket ) {
   /* C should come with auto-i ;) */
   int i;
@@ -255,6 +258,8 @@ void mutex_workqueue_pushsuccess( ot_taskid taskid ) {
 
 int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iovec *iovec ) {
   struct ot_task * task;
+  const char byte = 'o';
+
   /* Want exclusive access to tasklist */
   MTX_DBG( "pushresult locks.\n" );
   pthread_mutex_lock( &tasklist_mutex );
@@ -275,6 +280,8 @@ int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iove
   pthread_mutex_unlock( &tasklist_mutex );
   MTX_DBG( "pushresult unlocked.\n" );
 
+  io_trywrite( g_self_pipe[1], &byte, 1 );
+
   /* Indicate whether the worker has to throw away results */
   return task ? 0 : -1;
 }
diff --git a/trackerlogic.h b/trackerlogic.h
index 42cecb3..3857202 100644
--- a/trackerlogic.h
+++ b/trackerlogic.h
@@ -56,7 +56,7 @@ extern volatile int g_opentracker_running;
 #define       g_now_minutes (g_now_seconds/60)
 
 extern uint32_t g_tracker_id;
-typedef enum { FLAG_TCP, FLAG_UDP, FLAG_MCA } PROTO_FLAG;
+typedef enum { FLAG_TCP, FLAG_UDP, FLAG_MCA, FLAG_SELFPIPE } PROTO_FLAG;
 
 typedef struct {
   uint8_t data[OT_IP_SIZE+2+2];
-- 
cgit v1.2.3