@@ -789,21 +789,6 @@ struct v_threadpool {
789789 #include <signal.h>
790790#endif
791791
792- static struct v_threadpool_task * s_threadpool_get (v_threadpool * pool ) {
793- if (!pool )
794- return NULL ;
795- struct v_threadpool_task * task = pool -> first ;
796- if (!task )
797- return NULL ;
798- if (!task -> next ) {
799- pool -> first = NULL ;
800- pool -> last = NULL ;
801- } else {
802- pool -> first = task -> next ;
803- }
804- return task ;
805- }
806-
807792static void * v_threadpool_worker (void * arg ) {
808793#if !defined(WINDOWS ) && !defined(__APPLE__ )
809794 /* Block all signals, we linux may deliver them to any thread randomly.
@@ -813,13 +798,21 @@ static void *v_threadpool_worker(void *arg) {
813798 sigprocmask (SIG_SETMASK , & mask , 0 );
814799#endif
815800 v_threadpool * pool = arg ;
801+ if (!pool )
802+ return NULL ;
816803 while (1 ) {
817804 v_mutex_lock (pool -> mutex );
818805 while (!pool -> first && !pool -> stop_flag )
819806 v_cond_wait (pool -> work_available , pool -> mutex );
820807 if (pool -> stop_flag )
821808 break ;
822- struct v_threadpool_task * task = s_threadpool_get (pool );
809+ struct v_threadpool_task * task = pool -> first ;
810+ if (!task -> next ) {
811+ pool -> first = NULL ;
812+ pool -> last = NULL ;
813+ } else {
814+ pool -> first = task -> next ;
815+ }
823816 pool -> active_threads ++ ;
824817 v_mutex_release (pool -> mutex );
825818 if (task ) {
@@ -841,33 +834,42 @@ static void *v_threadpool_worker(void *arg) {
841834v_threadpool * v_threadpool_create (size_t n_threads ) {
842835 if (!n_threads )
843836 n_threads = v_sys_get_cores () + 1 ;
844- struct v_threadpool * pool = calloc (1 , sizeof (* pool ));
845- pool -> alive_threads = n_threads ;
846- pool -> mutex = v_mutex_create ();
847- pool -> work_available = v_cond_create ();
848- pool -> work_ongoing = v_cond_create ();
837+ v_threadpool * pool = calloc (1 , sizeof (* pool ));
838+ if (!pool )
839+ goto fail ;
840+ if (!(pool -> mutex = v_mutex_create ()))
841+ goto fail ;
842+ if (!(pool -> work_available = v_cond_create ()))
843+ goto fail ;
844+ if (!(pool -> work_ongoing = v_cond_create ()))
845+ goto fail ;
849846
850847 v_thread_ctx ctx = {
851848 .thread_fn = v_threadpool_worker ,
852849 .ctx = pool ,
853850 };
854- for (size_t i = 0 ; i < pool -> alive_threads ; ++ i ) {
855- v_thread * ret = v_thread_create (ctx , v_thread_type_detached );
856- if (!ret )
851+ for (size_t i = 0 ; i < n_threads ; ++ i ) {
852+ v_thread * success = v_thread_create (ctx , v_thread_type_detached );
853+ if (!success )
857854 goto fail ;
855+ pool -> alive_threads ++ ;
858856 }
859857 return pool ;
860858fail :
861- v_mutex_destroy (pool -> mutex );
862- v_cond_destroy (pool -> work_available );
863- v_cond_destroy (pool -> work_ongoing );
864- free (pool );
859+ v_threadpool_destroy (pool );
865860 return NULL ;
866861}
867862
868863void v_threadpool_destroy (v_threadpool * pool ) {
869864 if (!pool )
870865 return ;
866+ if (!pool -> mutex )
867+ goto no_mutex ;
868+ if (!pool -> work_available )
869+ goto no_work_available ;
870+ if (!pool -> work_ongoing )
871+ goto no_work_ongoing ;
872+
871873 v_mutex_lock (pool -> mutex );
872874 /* Clear queued tasks */
873875 struct v_threadpool_task * head = pool -> first ;
@@ -886,32 +888,30 @@ void v_threadpool_destroy(v_threadpool *pool) {
886888 v_threadpool_wait (pool );
887889
888890 /* Finish up */
889- v_mutex_destroy (pool -> mutex );
890- v_cond_destroy (pool -> work_available );
891891 v_cond_destroy (pool -> work_ongoing );
892+ no_work_ongoing :
893+ v_cond_destroy (pool -> work_available );
894+ no_work_available :
895+ v_mutex_destroy (pool -> mutex );
896+ no_mutex :
892897 free (pool );
893898}
894899
895- static struct v_threadpool_task * s_threadpool_task_create ( void (* fn )(void * arg ), void * arg ) {
900+ int v_threadpool_enqueue ( v_threadpool * pool , void (* fn )(void * arg ), void * arg ) {
896901 if (!fn )
897- return NULL ;
902+ return 1 ;
903+ if (!pool ) {
904+ fn (arg );
905+ return 0 ;
906+ }
898907 struct v_threadpool_task * task = malloc (sizeof (* task ));
908+ if (!task )
909+ return 1 ;
899910 * task = (struct v_threadpool_task ){
900911 .fn = fn ,
901912 .arg = arg ,
902913 .next = NULL ,
903914 };
904- return task ;
905- }
906-
907- int v_threadpool_enqueue (v_threadpool * pool , void (* fn )(void * arg ), void * arg ) {
908- if (!pool && fn ) {
909- fn (arg );
910- return 0 ;
911- }
912- struct v_threadpool_task * task = s_threadpool_task_create (fn , arg );
913- if (!task )
914- return 1 ;
915915 v_mutex_lock (pool -> mutex );
916916 if (!pool -> first ) {
917917 pool -> first = task ;
0 commit comments