aboutsummaryrefslogtreecommitdiff
path: root/src/Platform/Win32/Thread.c
blob: f256d87323c0726b7cacfb7f2445d0e0a957f193 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "Thread.h"

#include <process.h>


struct BH_ThreadContext
{
    BH_ThreadCallback callback;
    void *data;
};


static unsigned __stdcall threadRun(void *context)
{

    BH_ThreadCallback callback;
    void *data;

    callback = ((struct BH_ThreadContext *)context)->callback;
    data = ((struct BH_ThreadContext *)context)->data;
    free(context);

    callback(data);
    BH_TssCleanup();

    _endthreadex(0);
}


static int threadInit(BH_Thread *thread,
                      size_t stack,
                      BH_ThreadCallback callback,
                      void *data)
{
    struct BH_ThreadContext *context;

    context = malloc(sizeof(*context));
    if (!context)
        return BH_ERROR;
    context->callback = callback;
    context->data = data;

    thread->handle = (HANDLE)_beginthreadex(NULL, stack, BH_ThreadRun, context, 0, NULL);
    if (!thread->handle)
    {
        free(context);
        return BH_ERROR;
    }

    return BH_OK;
}


BH_Thread *BH_ThreadNew(size_t stack,
                        BH_ThreadCallback callback,
                        void *data)
{
    BH_Thread *thread;

    thread = malloc(sizeof(BH_Thread));
    if (thread && threadInit(thread, stack, callback, data))
    {
        free(thread);
        return NULL;
    }

    return thread;
}


int BH_ThreadJoin(BH_Thread *thread)
{
    /* Join the thread */
    WaitForSingleObject(thread->handle, INFINITE);
    CloseHandle(thread->handle);
    free(thread);

    return BH_OK;
}


int BH_ThreadDetach(BH_Thread *thread)
{
    /* Detach from thread */
    CloseHandle(thread->handle);
    free(thread);

    return BH_OK;
}