]> git.ipfire.org Git - thirdparty/opentracker.git/commitdiff
Fix tasklist iterators erdgeist-fix-tasklists
authorDirk Engling <erdgeist@erdgeist.org>
Fri, 8 Mar 2024 15:59:26 +0000 (16:59 +0100)
committerDirk Engling <erdgeist@erdgeist.org>
Fri, 8 Mar 2024 15:59:26 +0000 (16:59 +0100)
ot_mutex.c

index f46e3e25ed6a65acae1c16607ba55aa963f1eec3..12122456d2db70eaa87328514dcfefebc78e6e68 100644 (file)
@@ -72,24 +72,9 @@ static pthread_cond_t tasklist_being_filled;
 int mutex_workqueue_pushtask( int64 sock, ot_tasktype tasktype ) {
   struct ot_task ** tmptask, * task;
 
-  /* Want exclusive access to tasklist */
-  MTX_DBG( "pushtask locks.\n" );
-  pthread_mutex_lock( &tasklist_mutex );
-  MTX_DBG( "pushtask locked.\n" );
-
   task = malloc(sizeof( struct ot_task));
-  if( !task ) {
-    MTX_DBG( "pushtask fail unlocks.\n" );
-    pthread_mutex_unlock( &tasklist_mutex );
-    MTX_DBG( "pushtask fail unlocked.\n" );
+  if( !task )
     return -1;
-  }
-
-  /* Skip to end of list */
-  tmptask = &tasklist;
-  while( *tmptask )
-    tmptask = &(*tmptask)->next;
-  *tmptask = task;
 
   task->taskid        = 0;
   task->tasktype      = tasktype;
@@ -98,12 +83,18 @@ int mutex_workqueue_pushtask( int64 sock, ot_tasktype tasktype ) {
   task->iovec         = NULL;
   task->next          = 0;
 
+  /* Want exclusive access to tasklist */
+  pthread_mutex_lock( &tasklist_mutex );
+
+  /* Skip to end of list */
+  tmptask = &tasklist;
+  while( *tmptask )
+    tmptask = &(*tmptask)->next;
+  *tmptask = task;
+
   /* Inform waiting workers and release lock */
-  MTX_DBG( "pushtask broadcasts.\n" );
   pthread_cond_broadcast( &tasklist_being_filled );
-  MTX_DBG( "pushtask broadcasted, mutex unlocks.\n" );
   pthread_mutex_unlock( &tasklist_mutex );
-  MTX_DBG( "pushtask end mutex unlocked.\n" );
   return 0;
 }
 
@@ -111,31 +102,25 @@ void mutex_workqueue_canceltask( int64 sock ) {
   struct ot_task ** task;
 
   /* Want exclusive access to tasklist */
-  MTX_DBG( "canceltask locks.\n" );
   pthread_mutex_lock( &tasklist_mutex );
-  MTX_DBG( "canceltask locked.\n" );
-
-  task = &tasklist;
-  while( *task && ( (*task)->sock != sock ) )
-    *task = (*task)->next;
 
-  if( *task && ( (*task)->sock == sock ) ) {
-    struct iovec *iovec = (*task)->iovec;
-    struct ot_task *ptask = *task;
-    int i;
+  for (task = &tasklist; *task; task = &((*task)->next))
+    if ((*task)->sock == sock) {
+      struct iovec *iovec = (*task)->iovec;
+      struct ot_task *ptask = *task;
+      int i;
 
-    /* Free task's iovec */
-    for( i=0; i<(*task)->iovec_entries; ++i )
-      free( iovec[i].iov_base );
+      /* Free task's iovec */
+      for( i=0; i<(*task)->iovec_entries; ++i )
+        free( iovec[i].iov_base );
 
-    *task = (*task)->next;
-    free( ptask );
-  }
+      *task = (*task)->next;
+      free( ptask );
+      break;
+    }
 
   /* Release lock */
-  MTX_DBG( "canceltask unlocks.\n" );
   pthread_mutex_unlock( &tasklist_mutex );
-  MTX_DBG( "canceltask unlocked.\n" );
 }
 
 ot_taskid mutex_workqueue_poptask( ot_tasktype *tasktype ) {
@@ -143,33 +128,26 @@ ot_taskid mutex_workqueue_poptask( ot_tasktype *tasktype ) {
   ot_taskid taskid = 0;
 
   /* Want exclusive access to tasklist */
-  MTX_DBG( "poptask mutex locks.\n" );
   pthread_mutex_lock( &tasklist_mutex );
-  MTX_DBG( "poptask mutex locked.\n" );
 
   while( !taskid ) {
     /* Skip to the first unassigned task this worker wants to do */
-    task = tasklist;
-    while( task && ( ( ( TASK_CLASS_MASK & task->tasktype ) != *tasktype ) || task->taskid ) )
-      task = task->next;
-
-    /* If we found an outstanding task, assign a taskid to it
-       and leave the loop */
-    if( task ) {
-      task->taskid = taskid = ++next_free_taskid;
-      *tasktype = task->tasktype;
-    } else {
-      /* Wait until the next task is being fed */
-      MTX_DBG( "poptask cond waits.\n" );
+    for (task = tasklist; task; task = task->next)
+      if (!task->taskid && ( TASK_CLASS_MASK & task->tasktype ) == *tasktype) {
+        /* If we found an outstanding task, assign a taskid to it
+           and leave the loop */
+        task->taskid = taskid = ++next_free_taskid;
+        *tasktype = task->tasktype;
+        break;
+      }
+
+    /* Wait until the next task is being fed */
+    if (!taskid)
       pthread_cond_wait( &tasklist_being_filled, &tasklist_mutex );
-      MTX_DBG( "poptask cond waited.\n" );
-    }
   }
 
   /* Release lock */
-  MTX_DBG( "poptask end mutex unlocks.\n" );
   pthread_mutex_unlock( &tasklist_mutex );
-  MTX_DBG( "poptask end mutex unlocked.\n" );
 
   return taskid;
 }
@@ -178,24 +156,18 @@ void mutex_workqueue_pushsuccess( ot_taskid taskid ) {
   struct ot_task ** task;
 
   /* Want exclusive access to tasklist */
-  MTX_DBG( "pushsuccess locks.\n" );
   pthread_mutex_lock( &tasklist_mutex );
-  MTX_DBG( "pushsuccess locked.\n" );
-
-  task = &tasklist;
-  while( *task && ( (*task)->taskid != taskid ) )
-    *task = (*task)->next;
 
-  if( *task && ( (*task)->taskid == taskid ) ) {
-    struct ot_task *ptask = *task;
-    *task = (*task)->next;
-    free( ptask );
-  }
+  for (task = &tasklist; *task; task = &((*task)->next))
+    if ((*task)->taskid == taskid) {
+      struct ot_task *ptask = *task;
+      *task = (*task)->next;
+      free( ptask );
+      break;
+    }
 
   /* Release lock */
-  MTX_DBG( "pushsuccess unlocks.\n" );
   pthread_mutex_unlock( &tasklist_mutex );
-  MTX_DBG( "pushsuccess unlocked.\n" );
 }
 
 int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iovec *iovec ) {
@@ -203,24 +175,18 @@ int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iove
   const char byte = 'o';
 
   /* Want exclusive access to tasklist */
-  MTX_DBG( "pushresult locks.\n" );
   pthread_mutex_lock( &tasklist_mutex );
-  MTX_DBG( "pushresult locked.\n" );
 
-  task = tasklist;
-  while( task && ( task->taskid != taskid ) )
-    task = task->next;
-
-  if( task ) {
-    task->iovec_entries = iovec_entries;
-    task->iovec         = iovec;
-    task->tasktype      = TASK_DONE;
-  }
+  for (task = tasklist; task; task = task->next)
+    if (task->taskid == taskid) {
+      task->iovec_entries = iovec_entries;
+      task->iovec         = iovec;
+      task->tasktype      = TASK_DONE;
+      break;
+    }
 
   /* Release lock */
-  MTX_DBG( "pushresult unlocks.\n" );
   pthread_mutex_unlock( &tasklist_mutex );
-  MTX_DBG( "pushresult unlocked.\n" );
 
   io_trywrite( g_self_pipe[1], &byte, 1 );
 
@@ -233,29 +199,23 @@ int64 mutex_workqueue_popresult( int *iovec_entries, struct iovec ** iovec ) {
   int64 sock = -1;
 
   /* Want exclusive access to tasklist */
-  MTX_DBG( "popresult locks.\n" );
   pthread_mutex_lock( &tasklist_mutex );
-  MTX_DBG( "popresult locked.\n" );
-
-  task = &tasklist;
-  while( *task && ( (*task)->tasktype != TASK_DONE ) )
-    task = &(*task)->next;
 
-  if( *task && ( (*task)->tasktype == TASK_DONE ) ) {
-    struct ot_task *ptask = *task;
+  for (task = &tasklist; *task; task = &((*task)->next))
+    if ((*task)->tasktype == TASK_DONE) {
+      struct ot_task *ptask = *task;
 
-    *iovec_entries = (*task)->iovec_entries;
-    *iovec         = (*task)->iovec;
-    sock           = (*task)->sock;
+      *iovec_entries = (*task)->iovec_entries;
+      *iovec         = (*task)->iovec;
+      sock           = (*task)->sock;
 
-    *task = (*task)->next;
-    free( ptask );
-  }
+      *task = (*task)->next;
+      free( ptask );
+      break;
+    }
 
   /* Release lock */
-  MTX_DBG( "popresult unlocks.\n" );
   pthread_mutex_unlock( &tasklist_mutex );
-  MTX_DBG( "popresult unlocked.\n" );
   return sock;
 }