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 18 namespace BKernel { 19 20 21 class DPCQueue; 22 23 24 class DPCCallback : public DoublyLinkedListLinkImpl<DPCCallback> { 25 public: 26 DPCCallback(); 27 virtual ~DPCCallback(); 28 29 virtual void DoDPC(DPCQueue* queue) = 0; 30 31 private: 32 friend class DPCQueue; 33 34 private: 35 DPCQueue* fInQueue; 36 }; 37 38 39 class FunctionDPCCallback : public DPCCallback { 40 public: 41 FunctionDPCCallback(DPCQueue* owner); 42 43 void SetTo(void (*function)(void*), void* argument); 44 45 virtual void DoDPC(DPCQueue* queue); 46 47 private: 48 DPCQueue* fOwner; 49 void (*fFunction)(void*); 50 void* fArgument; 51 }; 52 53 54 class DPCQueue { 55 public: 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 Thread()69 thread_id Thread() const 70 { return fThreadID; } 71 72 public: 73 // conceptually package private 74 void Recycle(FunctionDPCCallback* callback); 75 76 private: 77 typedef DoublyLinkedList<DPCCallback> CallbackList; 78 79 private: 80 static status_t _ThreadEntry(void* data); 81 status_t _Thread(); 82 _IsClosed()83 bool _IsClosed() const 84 { return fThreadID < 0; } 85 86 private: 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 100 using BKernel::DPCCallback; 101 using BKernel::DPCQueue; 102 using BKernel::FunctionDPCCallback; 103 104 105 __BEGIN_DECLS 106 107 void dpc_init(); 108 109 __END_DECLS 110 111 112 #endif // _KERNEL_DPC_H 113