3 * - By John Hodge (thePowersGang)
6 * - UDI Deferred call code
8 * Used to prevent excessive recursion causing stack exhaustion
13 #include "udi_internal.h"
14 #include <workqueue.h>
17 void UDI_int_Deferred_UnmashalCb(tUDI_DeferredCall *Call);
18 void UDI_int_Deferred_UnmashalCbU8(tUDI_DeferredCall *Call);
19 void UDI_int_Deferred_UnmashalCbS(tUDI_DeferredCall *Call);
22 tWorkqueue gUDI_DeferredWorkQueue;
25 void UDI_int_DeferredThread(void *unused)
27 Threads_SetName("UDI Deferred");
28 Workqueue_Init(&gUDI_DeferredWorkQueue, "UDI Deferred", offsetof(tUDI_DeferredCall, Next));
32 tUDI_DeferredCall *call = Workqueue_GetWork(&gUDI_DeferredWorkQueue);
36 Log_Notice("UDI", "Deferred thread worken with no work");
40 // Ummarshal calls handler and frees the call
41 call->Unmarshal( call );
45 void UDI_int_AddDeferred(tUDI_DeferredCall *Call)
47 Workqueue_AddWork(&gUDI_DeferredWorkQueue, Call);
50 tUDI_DeferredCall *UDI_int_AllocDeferred(udi_cb_t *cb, udi_op_t *handler, tUDI_DeferredUnmarshal *Unmarshal, size_t extra)
52 tUDI_DeferredCall *ret = NEW( tUDI_DeferredCall, + extra );
53 ret->Unmarshal = Unmarshal;
54 ret->Handler = handler;
60 typedef void udi_op_cb_t(udi_cb_t *gcb);
61 void UDI_int_MakeDeferredCb(udi_cb_t *cb, udi_op_t *handler)
63 tUDI_DeferredCall *call = UDI_int_AllocDeferred(cb, handler, UDI_int_Deferred_UnmashalCb, 0);
64 UDI_int_AddDeferred(call);
66 void UDI_int_Deferred_UnmashalCb(tUDI_DeferredCall *Call)
68 UDI_int_ChannelReleaseFromCall(Call->cb);
69 ((udi_op_cb_t*)Call->Handler)(Call->cb);
73 typedef void udi_op_cbu8_t(udi_cb_t *gcb, udi_ubit8_t arg1);
77 void UDI_int_MakeDeferredCbU8(udi_cb_t *cb, udi_op_t *handler, udi_ubit8_t arg1)
79 struct sData_CbU8 *data;
80 tUDI_DeferredCall *call = UDI_int_AllocDeferred(cb, handler, UDI_int_Deferred_UnmashalCbU8, sizeof(*data));
81 data = (void*)(call + 1);
83 UDI_int_AddDeferred(call);
85 void UDI_int_Deferred_UnmashalCbU8(tUDI_DeferredCall *Call)
87 struct sData_CbU8 *data = (void*)(Call+1);
88 UDI_int_ChannelReleaseFromCall(Call->cb);
89 ((udi_op_cbu8_t*)Call->Handler)(Call->cb, data->arg1);
93 typedef void udi_op_cbs_t(udi_cb_t *gcb, udi_status_t status);
97 void UDI_int_MakeDeferredCbS(udi_cb_t *cb, udi_op_t *handler, udi_status_t status)
99 struct sData_CbS *data;
100 tUDI_DeferredCall *call = UDI_int_AllocDeferred(cb, handler, UDI_int_Deferred_UnmashalCbS, sizeof(*data));
101 data = (void*)(call + 1);
102 data->status = status;
103 UDI_int_AddDeferred(call);
105 void UDI_int_Deferred_UnmashalCbS(tUDI_DeferredCall *Call)
107 struct sData_CbS *data = (void*)(Call+1);
108 UDI_int_ChannelReleaseFromCall(Call->cb);
109 ((udi_op_cbs_t*)Call->Handler)(Call->cb, data->status);