1/*
2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _KERNEL_DPC_H
6#define _KERNEL_DPC_H
7
8
9#include <sys/cdefs.h>
10
11#include <KernelExport.h>
12
13#include <util/DoublyLinkedList.h>
14
15#include <condition_variable.h>
16
17
18namespace BKernel {
19
20
21class DPCQueue;
22
23
24class DPCCallback : public DoublyLinkedListLinkImpl<DPCCallback> {
25public:
26								DPCCallback();
27	virtual						~DPCCallback();
28
29	virtual	void				DoDPC(DPCQueue* queue) = 0;
30
31private:
32			friend class DPCQueue;
33
34private:
35			DPCQueue*			fInQueue;
36};
37
38
39class FunctionDPCCallback : public DPCCallback {
40public:
41								FunctionDPCCallback(DPCQueue* owner);
42
43			void				SetTo(void (*function)(void*), void* argument);
44
45	virtual	void				DoDPC(DPCQueue* queue);
46
47private:
48			DPCQueue*			fOwner;
49			void 				(*fFunction)(void*);
50			void*				fArgument;
51};
52
53
54class DPCQueue {
55public:
56								DPCQueue();
57								~DPCQueue();
58
59	static	DPCQueue*			DefaultQueue(int priority);
60
61			status_t			Init(const char* name, int32 priority,
62									uint32 reservedSlots);
63			void				Close(bool cancelPending);
64
65			status_t			Add(DPCCallback* callback);
66			status_t			Add(void (*function)(void*), void* argument);
67			bool				Cancel(DPCCallback* callback);
68
69			thread_id			Thread() const
70									{ return fThreadID; }
71
72public:
73			// conceptually package private
74			void				Recycle(FunctionDPCCallback* callback);
75
76private:
77			typedef DoublyLinkedList<DPCCallback> CallbackList;
78
79private:
80	static	status_t			_ThreadEntry(void* data);
81			status_t			_Thread();
82
83			bool				_IsClosed() const
84									{ return fThreadID < 0; }
85
86private:
87			spinlock			fLock;
88			thread_id			fThreadID;
89			CallbackList		fCallbacks;
90			CallbackList		fUnusedFunctionCallbacks;
91			ConditionVariable	fPendingCallbacksCondition;
92			DPCCallback*		fCallbackInProgress;
93			ConditionVariable*	fCallbackDoneCondition;
94};
95
96
97}	// namespace BKernel
98
99
100using BKernel::DPCCallback;
101using BKernel::DPCQueue;
102using BKernel::FunctionDPCCallback;
103
104
105__BEGIN_DECLS
106
107void		dpc_init();
108
109__END_DECLS
110
111
112#endif	// _KERNEL_DPC_H
113