aboutsummaryrefslogtreecommitdiff
path: root/Src/nu/threadpool/api_threadpool.h
blob: 4cf5ab4f6a0d1542ffef3f7319d32e5fc7e45f34 (plain) (blame)
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
90
91
92
#pragma once

#include <windows.h>
#include <bfc/platform/types.h>
#include <bfc/dispatch.h>

class ThreadID;

class api_threadpool : public Dispatchable
{
protected:
	api_threadpool() {}
	~api_threadpool() {}
public:
	typedef int (*ThreadPoolFunc)(HANDLE handle, void *user_data, intptr_t id);
	enum
	{
		// pass this flag to AddHandle or RunFunction indicate that your thread function
		// might run for a long time
		FLAG_LONG_EXECUTION  = 0x1,
		FLAG_REQUIRE_COM_STA = 0x2,
		FLAG_REQUIRE_COM_MT  = 0x4,
		MASK_COM_FLAGS       = 0x6,
	};

public:
	ThreadID *ReserveThread(int flags);
	/* Release a thread you've previously reserved */
	void ReleaseThread(ThreadID *thread_id);

	/* adds a waitable handle to the thread pool.  when the event is signalled, your function ptr will get called 
	user_data and id values get passed to your function.
	your function should return 1 to indicate that it can be removed
	flags, see api_threadpool	*/
	int AddHandle(ThreadID *threadid, HANDLE handle, api_threadpool::ThreadPoolFunc func, void *user_data, intptr_t id, int flags);
	void RemoveHandle(ThreadID *threadid, HANDLE handle);
	int RunFunction(ThreadID *threadid, api_threadpool::ThreadPoolFunc func, void *user_data, intptr_t id, int flags);

	size_t GetNumberOfThreads(); // total number of threads in the threadpool
	size_t GetNumberOfActiveThreads(); // number of threads that are currently being used (inside user function but not necessarily busy)

	enum
	{
		RESERVETHREAD            = 0,
		RELEASETHREAD            = 1,
		ADDHANDLE                = 2,
		REMOVEHANDLE             = 3,
		RUNFUNCTION              = 4,
		GETNUMBEROFTHREADS       = 5,
		GETNUMBEROFACTIVETHREADS = 6,
	};
};

inline ThreadID *api_threadpool::ReserveThread(int flags)
{
	return _call(RESERVETHREAD, (ThreadID *)0, flags);
}

inline void api_threadpool::ReleaseThread(ThreadID *thread_id)
{
	_voidcall(RELEASETHREAD, thread_id);
}

inline int api_threadpool::AddHandle(ThreadID *threadid, HANDLE handle, api_threadpool::ThreadPoolFunc func, void *user_data, intptr_t id, int flags)
{
	return _call(ADDHANDLE, (int)1, threadid, handle, func, user_data, id, flags);
}

inline void api_threadpool::RemoveHandle(ThreadID *threadid, HANDLE handle)
{
	_voidcall(REMOVEHANDLE, threadid, handle);
}

inline int api_threadpool::RunFunction(ThreadID *threadid, api_threadpool::ThreadPoolFunc func, void *user_data, intptr_t id, int flags)
{
	return _call(RUNFUNCTION, (int)1, threadid, func, user_data, id, flags);
}

inline size_t api_threadpool::GetNumberOfThreads()
{
	return _call(GETNUMBEROFTHREADS, (size_t)0);
}

inline size_t api_threadpool::GetNumberOfActiveThreads()
{
	return _call(GETNUMBEROFACTIVETHREADS, (size_t)0);
}

// {4DE015D3-11D8-4ac6-A3E6-216DF5252107}
static const GUID ThreadPoolGUID = 
{ 0x4de015d3, 0x11d8, 0x4ac6, { 0xa3, 0xe6, 0x21, 0x6d, 0xf5, 0x25, 0x21, 0x7 } };