Author: ion
Date: Tue Jan 16 08:31:05 2007
New Revision: 25483
URL:
http://svn.reactos.org/svn/reactos?rev=25483&view=rev
Log:
- Start partial implementation of Executive Lightweight Callbacks: ExAllocateCallBack,
ExInitializeCallBack, ExFreeCallBack, ExWaitForCallBacks, ExGetCallBackBlockRoutine,
ExGetcallBackBlockContext, ExDoCallBack.
- Stub ExReferenceCallBackBlock and ExDereferenceCallBackBlock until I get the locking
right.
- These callbacks are used by Cm as well as Ps inside Windows NT and combine the power of
PushLocks, Rundown Protection and Fast Referencing to ensure callbacks only get called
once and thread safely. Not yet used in ROS.
Modified:
trunk/reactos/include/ndk/extypes.h
trunk/reactos/ntoskrnl/ex/callback.c
Modified: trunk/reactos/include/ndk/extypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/extypes.h?rev=…
==============================================================================
--- trunk/reactos/include/ndk/extypes.h (original)
+++ trunk/reactos/include/ndk/extypes.h Tue Jan 16 08:31:05 2007
@@ -514,7 +514,7 @@
typedef struct _EX_CALLBACK_ROUTINE_BLOCK
{
EX_RUNDOWN_REF RundownProtect;
- PVOID Function;
+ PEX_CALLBACK_FUNCTION Function;
PVOID Context;
} EX_CALLBACK_ROUTINE_BLOCK, *PEX_CALLBACK_ROUTINE_BLOCK;
Modified: trunk/reactos/ntoskrnl/ex/callback.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/callback.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/callback.c (original)
+++ trunk/reactos/ntoskrnl/ex/callback.c Tue Jan 16 08:31:05 2007
@@ -39,6 +39,110 @@
KEVENT ExpCallbackEvent;
/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+ExInitializeCallback(IN OUT PEX_CALLBACK Callback)
+{
+ /* Initialize the fast references */
+ Callback->RoutineBlock.Object = NULL;
+}
+
+PEX_CALLBACK_ROUTINE_BLOCK
+NTAPI
+ExAllocateCallBack(IN PEX_CALLBACK_FUNCTION Function,
+ IN PVOID Context)
+{
+ PEX_CALLBACK_ROUTINE_BLOCK Callback;
+
+ /* Allocate a callback */
+ Callback = ExAllocatePoolWithTag(PagedPool,
+ sizeof(*Callback),
+ TAG('C', 'b', 'r',
'b'));
+ if (Callback)
+ {
+ /* Initialize it */
+ Callback->Function = Function;
+ Callback->Context = Context;
+ ExInitializeRundownProtection(&Callback->RundownProtect);
+ }
+
+ /* Return it */
+ return Callback;
+}
+
+VOID
+NTAPI
+ExFreeCallback(IN PEX_CALLBACK_ROUTINE_BLOCK Callback)
+{
+ /* Just free it from memory */
+ ExFreePool(Callback);
+}
+
+VOID
+NTAPI
+ExWaitForCallBacks(IN PEX_CALLBACK_ROUTINE_BLOCK Callback)
+{
+ /* Wait on the rundown */
+ ExWaitForRundownProtectionRelease(&Callback->RundownProtect);
+}
+
+PEX_CALLBACK_FUNCTION
+NTAPI
+ExGetCallBackBlockRoutine(IN PEX_CALLBACK_ROUTINE_BLOCK Callback)
+{
+ /* Return the function */
+ return Callback->Function;
+}
+
+PVOID
+NTAPI
+ExGetCallBackBlockContext(IN PEX_CALLBACK_ROUTINE_BLOCK Callback)
+{
+ /* Return the context */
+ return Callback->Context;
+}
+
+VOID
+NTAPI
+ExDereferenceCallBackBlock(IN OUT PEX_CALLBACK CallBack,
+ IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock)
+{
+ /* FIXME: TODO */
+}
+
+PEX_CALLBACK_ROUTINE_BLOCK
+NTAPI
+ExReferenceCallBackBlock(IN OUT PEX_CALLBACK CallBack)
+{
+ /* FIXME: TODO */
+ return NULL;
+}
+
+VOID
+NTAPI // FIXME: FORCEINLINE AFTER TESTING!
+ExDoCallBack(IN OUT PEX_CALLBACK Callback,
+ IN PVOID Context,
+ IN PVOID Argument1,
+ IN PVOID Argument2)
+{
+ PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock;
+ PEX_CALLBACK_FUNCTION Function;
+
+ /* Reference the block */
+ CallbackRoutineBlock = ExReferenceCallBackBlock(Callback);
+ if (CallbackRoutineBlock)
+ {
+ /* Get the function */
+ Function = ExGetCallBackBlockRoutine(CallbackRoutineBlock);
+
+ /* Do the callback */
+ Function(Context, Argument1, Argument2);
+
+ /* Now dereference it */
+ ExDereferenceCallBackBlock(Callback, CallbackRoutineBlock);
+ }
+}
VOID
NTAPI