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 bool schedulerLocked); 67 status_t Add(void (*function)(void*), void* argument, 68 bool schedulerLocked); 69 bool Cancel(DPCCallback* callback); 70 71 thread_id Thread() const 72 { return fThreadID; } 73 74 public: 75 // conceptually package private 76 void Recycle(FunctionDPCCallback* callback); 77 78 private: 79 typedef DoublyLinkedList<DPCCallback> CallbackList; 80 81 private: 82 static status_t _ThreadEntry(void* data); 83 status_t _Thread(); 84 85 bool _IsClosed() const 86 { return fThreadID < 0; } 87 88 private: 89 spinlock fLock; 90 thread_id fThreadID; 91 CallbackList fCallbacks; 92 CallbackList fUnusedFunctionCallbacks; 93 ConditionVariable fPendingCallbacksCondition; 94 DPCCallback* fCallbackInProgress; 95 ConditionVariable* fCallbackDoneCondition; 96 }; 97 98 99 } // namespace BKernel 100 101 102 using BKernel::DPCCallback; 103 using BKernel::DPCQueue; 104 using BKernel::FunctionDPCCallback; 105 106 107 __BEGIN_DECLS 108 109 void dpc_init(); 110 111 __END_DECLS 112 113 114 #endif // _KERNEL_DPC_H 115