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 LOG("Added deferred %p{um=%p,cb=%p,handler=%p}",
48 Call, Call->Unmarshal, Call->cb, Call->Handler);
49 Workqueue_AddWork(&gUDI_DeferredWorkQueue, Call);
52 tUDI_DeferredCall *UDI_int_AllocDeferred(udi_cb_t *cb, udi_op_t *handler, tUDI_DeferredUnmarshal *Unmarshal, size_t extra)
54 tUDI_DeferredCall *ret = NEW( tUDI_DeferredCall, + extra );
55 ret->Unmarshal = Unmarshal;
56 ret->Handler = handler;
62 typedef void udi_op_cb_t(udi_cb_t *gcb);
63 void UDI_int_MakeDeferredCb(udi_cb_t *cb, udi_op_t *handler)
65 tUDI_DeferredCall *call = UDI_int_AllocDeferred(cb, handler, UDI_int_Deferred_UnmashalCb, 0);
66 UDI_int_AddDeferred(call);
68 void UDI_int_Deferred_UnmashalCb(tUDI_DeferredCall *Call)
70 UDI_int_ChannelReleaseFromCall(Call->cb);
71 ((udi_op_cb_t*)Call->Handler)(Call->cb);
75 typedef void udi_op_cbu8_t(udi_cb_t *gcb, udi_ubit8_t arg1);
79 void UDI_int_MakeDeferredCbU8(udi_cb_t *cb, udi_op_t *handler, udi_ubit8_t arg1)
81 struct sData_CbU8 *data;
82 tUDI_DeferredCall *call = UDI_int_AllocDeferred(cb, handler, UDI_int_Deferred_UnmashalCbU8, sizeof(*data));
83 data = (void*)(call + 1);
85 UDI_int_AddDeferred(call);
87 void UDI_int_Deferred_UnmashalCbU8(tUDI_DeferredCall *Call)
89 struct sData_CbU8 *data = (void*)(Call+1);
90 UDI_int_ChannelReleaseFromCall(Call->cb);
91 ((udi_op_cbu8_t*)Call->Handler)(Call->cb, data->arg1);
95 typedef void udi_op_cbs_t(udi_cb_t *gcb, udi_status_t status);
99 void UDI_int_MakeDeferredCbS(udi_cb_t *cb, udi_op_t *handler, udi_status_t status)
101 struct sData_CbS *data;
102 tUDI_DeferredCall *call = UDI_int_AllocDeferred(cb, handler, UDI_int_Deferred_UnmashalCbS, sizeof(*data));
103 data = (void*)(call + 1);
104 data->status = status;
105 UDI_int_AddDeferred(call);
107 void UDI_int_Deferred_UnmashalCbS(tUDI_DeferredCall *Call)
109 struct sData_CbS *data = (void*)(Call+1);
110 UDI_int_ChannelReleaseFromCall(Call->cb);
111 ((udi_op_cbs_t*)Call->Handler)(Call->cb, data->status);