2022-06-21 11:51 (UTC-0700), Tyler Retzlaff: > > > +int > > > +rte_thread_join(rte_thread_t thread_id, unsigned long *value_ptr) > > > +{ > > > + int ret = 0; > > > + void *res = NULL; > > > + void **pres = NULL; > > > + > > > + if (value_ptr != NULL) > > > + pres = &res; > > > + > > > + ret = pthread_join((pthread_t)thread_id.opaque_id, pres); > > > + if (ret != 0) { > > > + RTE_LOG(DEBUG, EAL, "pthread_join failed\n"); > > > + return ret; > > > + } > > > + > > > + if (value_ptr != NULL && *pres != NULL) > > > + *value_ptr = *(unsigned long *)(*pres); > > > + > > > + return 0; > > > +} > > > > What makes *pres == NULL special? > > it's not clear what you mean, can you explain? maybe there is some > context i am missing from the original patch series?
There's no previous context. After ptread_join(), *pres holds the return value of the thread routine. You only assign *value_ptr if value_ptr is not NULL (obviously correct) and if *pres != NULL, that is, if the thread returned a non-NULL value. But this value is opaque, why do you filter NULL? Perhaps you meant if (pres != NULL), no dereference? > > > +int > > > +rte_thread_create(rte_thread_t *thread_id, > > > + const rte_thread_attr_t *thread_attr, > > > + rte_thread_func thread_func, void *args) > > > +{ > > > + int ret = 0; > > > + DWORD tid; > > > + HANDLE thread_handle = NULL; > > > + GROUP_AFFINITY thread_affinity; > > > + struct thread_routine_ctx *ctx = NULL; > > > + > > > + ctx = calloc(1, sizeof(*ctx)); > > > + if (ctx == NULL) { > > > + RTE_LOG(DEBUG, EAL, "Insufficient memory for thread context > > > allocations\n"); > > > + ret = ENOMEM; > > > + goto cleanup; > > > + } > > > + ctx->routine_args = args; > > > + ctx->thread_func = thread_func; > > > + > > > + thread_handle = CreateThread(NULL, 0, thread_func_wrapper, ctx, > > > + CREATE_SUSPENDED, &tid); > > > + if (thread_handle == NULL) { > > > + ret = thread_log_last_error("CreateThread()"); > > > + free(ctx); > > > + goto cleanup; > > > > Missing `free(ctx)` from other error paths below. > > beyond this point free(ctx) will happen in thread_func_wrapper. i will > add a comment to make it clear. Not if you exit before ResumeThread() and thread_func_wrapper() will never execute to call free().