Skip to content

Commit

Permalink
win: fix uv_thread_self()
Browse files Browse the repository at this point in the history
59658a8 changed uv_thread_self()
to return uv_thread_t, but uv_thread_t is a thread's HANDLE while
uv_thread_self() returns the current thread's id.
This means that uv_thread_equal() is also broken, as we are
potentially comparing HANDLES to ids.

Changed uv_thread_self() to return the current thread's creation handle.
Fixed small doc issue.
  • Loading branch information
orangemocha authored and saghul committed Nov 10, 2014
1 parent 0f25560 commit 6591d00
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 59 deletions.
2 changes: 1 addition & 1 deletion docs/src/threading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Threads
^^^^^^^

.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg)
.. c:function:: unsigned long uv_thread_self(void)
.. c:function:: uv_thread_t uv_thread_self(void)
.. c:function:: int uv_thread_join(uv_thread_t *tid)
.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2)
Expand Down
45 changes: 45 additions & 0 deletions src/unix/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,51 @@
#undef NANOSEC
#define NANOSEC ((uint64_t) 1e9)


struct thread_ctx {
void (*entry)(void* arg);
void* arg;
};


static void* uv__thread_start(void *arg)
{
struct thread_ctx *ctx_p;
struct thread_ctx ctx;

ctx_p = arg;
ctx = *ctx_p;
free(ctx_p);
ctx.entry(ctx.arg);

return 0;
}


int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
struct thread_ctx* ctx;
int err;

ctx = malloc(sizeof(*ctx));
if (ctx == NULL)
return UV_ENOMEM;

ctx->entry = entry;
ctx->arg = arg;

err = pthread_create(tid, NULL, uv__thread_start, ctx);

if (err)
free(ctx);

return err ? -1 : 0;
}


uv_thread_t uv_thread_self(void) {
return pthread_self();
}

int uv_thread_join(uv_thread_t *tid) {
return -pthread_join(*tid, NULL);
}
Expand Down
58 changes: 0 additions & 58 deletions src/uv-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,64 +257,6 @@ int uv_udp_recv_stop(uv_udp_t* handle) {
}


struct thread_ctx {
void (*entry)(void* arg);
void* arg;
};


#ifdef _WIN32
static UINT __stdcall uv__thread_start(void* arg)
#else
static void* uv__thread_start(void *arg)
#endif
{
struct thread_ctx *ctx_p;
struct thread_ctx ctx;

ctx_p = arg;
ctx = *ctx_p;
free(ctx_p);
ctx.entry(ctx.arg);

return 0;
}


int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
struct thread_ctx* ctx;
int err;

ctx = malloc(sizeof(*ctx));
if (ctx == NULL)
return UV_ENOMEM;

ctx->entry = entry;
ctx->arg = arg;

#ifdef _WIN32
*tid = (HANDLE) _beginthreadex(NULL, 0, uv__thread_start, ctx, 0, NULL);
err = *tid ? 0 : errno;
#else
err = pthread_create(tid, NULL, uv__thread_start, ctx);
#endif

if (err)
free(ctx);

return err ? -1 : 0;
}


uv_thread_t uv_thread_self(void) {
#ifdef _WIN32
return GetCurrentThreadId();
#else
return pthread_self();
#endif
}


void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
QUEUE* q;
uv_handle_t* h;
Expand Down
62 changes: 62 additions & 0 deletions src/win/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,68 @@ void uv_once(uv_once_t* guard, void (*callback)(void)) {
uv__once_inner(guard, callback);
}

static UV_THREAD_LOCAL uv_thread_t uv__current_thread = NULL;

struct thread_ctx {
void (*entry)(void* arg);
void* arg;
uv_thread_t self;
};


static UINT __stdcall uv__thread_start(void* arg)
{
struct thread_ctx *ctx_p;
struct thread_ctx ctx;

ctx_p = arg;
ctx = *ctx_p;
free(ctx_p);

uv__current_thread = ctx.self;
ctx.entry(ctx.arg);

return 0;
}


int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
struct thread_ctx* ctx;
int err;
HANDLE thread;

ctx = malloc(sizeof(*ctx));
if (ctx == NULL)
return UV_ENOMEM;

ctx->entry = entry;
ctx->arg = arg;

/* Create the thread in suspended state so we have a chance to pass
* its own creation handle to it */

This comment has been minimized.

Copy link
@trevnorris

trevnorris Dec 10, 2014

Member

nit: whitespace at end of comment

This comment has been minimized.

Copy link
@txdv

txdv Dec 10, 2014

Contributor

Can you see it in github?

This comment has been minimized.

Copy link
@trevnorris

trevnorris Dec 12, 2014

Member

I did a git apply of the patch and it let me know there was whitespace at the end of this line. You can see it here if you highlight the entire line.

thread = (HANDLE) _beginthreadex(NULL,
0,
uv__thread_start,
ctx,
CREATE_SUSPENDED,
NULL);
if (thread == NULL) {
err = errno;
free(ctx);
} else {
err = 0;
*tid = thread;
ctx->self = thread;
ResumeThread(thread);
}

return err;
}


uv_thread_t uv_thread_self(void) {
return uv__current_thread;
}

int uv_thread_join(uv_thread_t *tid) {
if (WaitForSingleObject(*tid, INFINITE))
Expand Down

0 comments on commit 6591d00

Please sign in to comment.