diff options
-rw-r--r-- | src/worker.c | 83 | ||||
-rw-r--r-- | src/workertest.c | 2 |
2 files changed, 58 insertions, 27 deletions
diff --git a/src/worker.c b/src/worker.c index 6cfa1bb..a7554a4 100644 --- a/src/worker.c +++ b/src/worker.c @@ -58,52 +58,74 @@ typedef struct { GPid pid; gint out, err; worker_t *worker; + pthread_t thread; + GMainLoop *main_loop; } direct_glib_execution_worker_data_t; static void watch_child( GPid pid, gint status, gpointer *data ) { - printf( "ENDENDEND %d\n", pid ); + direct_glib_execution_worker_data_t *wed = (direct_glib_execution_worker_data_t *)data; + + printf( "Worker child with PID %d terminated.\n", wed->pid ); + g_spawn_close_pid( pid ); + + g_main_loop_quit( wed->main_loop ); } - -int worker_init( worker_t *worker ) + +static void *worker_func( void *thread_data ) { - if( worker->state == WORKER_STATE_RUNNING ) { - return 0; - } - + direct_glib_execution_worker_data_t *wed = (direct_glib_execution_worker_data_t *)thread_data; + worker_t *worker = wed->worker; + gchar *argv[] = { worker->command, NULL }; - worker->execution_data = malloc( sizeof( direct_glib_execution_worker_data_t ) ); - direct_glib_execution_worker_data_t *wed = - (direct_glib_execution_worker_data_t *)worker->execution_data; - wed->worker = worker; gboolean ret = g_spawn_async_with_pipes( NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &wed->pid, NULL, &wed->out, &wed->err, NULL ); if( !ret ) { g_error( "Starting worker failed" ); - return -1; + return NULL; } GMainContext *context = g_main_context_default( ); - GMainLoop *main_loop = g_main_loop_new( context, TRUE ); + wed->main_loop = g_main_loop_new( context, TRUE ); g_child_watch_add( wed->pid, (GChildWatchFunc)watch_child, (gpointer *)wed ); - // TODO: first one blocks (of course).. - //~ g_main_loop_run( main_loop ); + worker->state = WORKER_STATE_RUNNING; + + g_main_loop_run( wed->main_loop ); + + worker->state = WORKER_STATE_STOPPED; + + return NULL; +} + +int worker_init( worker_t *worker ) +{ + if( worker->state == WORKER_STATE_RUNNING ) { + return 0; + } + + pthread_attr_t attr; + int res; - // .. second one should go into the coordinator loop - // (and should not leak the glib-based implementation - // to the coordinator) - //~ for( ;; ) { - //~ gboolean res = g_main_context_iteration( context, FALSE ); - //~ sleep( 1 ); - //~ } + res = pthread_attr_init( &attr ); + if( res != 0 ) { + return 1; + } + + worker->execution_data = malloc( sizeof( direct_glib_execution_worker_data_t ) ); + direct_glib_execution_worker_data_t *wed = + (direct_glib_execution_worker_data_t *)worker->execution_data; + wed->worker = worker; - worker->state = WORKER_STATE_RUNNING; - + res = pthread_create( &wed->thread, &attr, worker_func, (void *)wed ); + if( res != 0 ) { + return 1; + } + return 0; } @@ -121,7 +143,16 @@ void worker_terminate( worker_t *worker ) worker->execution_data = NULL; } -int worker_free( ) +int worker_free( worker_t *worker ) { - return 0; + direct_glib_execution_worker_data_t *wed = (direct_glib_execution_worker_data_t *)worker->execution_data; + void *result; + int res; + + res = pthread_join( wed->thread, &result ); + if( res != 0 ) { + return 1; + } + + return 0; } diff --git a/src/workertest.c b/src/workertest.c index ecc980e..51fc717 100644 --- a/src/workertest.c +++ b/src/workertest.c @@ -2,7 +2,7 @@ #include "port.h" -#define RUN_TIME 60 +#define RUN_TIME 10 int main( void ) { |