Reapplied r44918 (as far as it applies to fat-handler):
[AROS.git] / rom / dbus / test / dbus-amiga.c
blob3e44ded194b5aaf8450612ba18165311fd15156e
1 /*
2 * AmigaOS D-BUS connection handling using a slave process as the main
3 * loop.
4 */
6 #include <dos/dostags.h>
7 #include <exec/tasks.h>
9 #include <clib/alib_protos.h>
10 #define DBUS_API_SUBJECT_TO_CHANGE
11 #include <proto/dbus.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
15 #define DEBUG 1
16 #include <aros/debug.h>
18 #include "dbus-amiga.h"
20 struct WatchData {
21 struct MinNode node;
22 BOOL enabled;
23 DBusWatch* watch;
26 struct ConnectionData {
27 struct Task* main;
28 struct Task* creator;
29 BYTE signal;
30 struct MinList watches;
31 DBusConnection* connection;
34 static dbus_int32_t Slot = -1;
36 static void DeleteConnectionData(struct ConnectionData* c);
37 static void CleanupAmigaConnection(void* data);
39 static void MainLoop() {
40 struct ConnectionData* c = (struct ConnectionData*) FindTask(NULL)->tc_UserData;
41 kprintf("MainLoop started %08lx (cd %08lx)\n", FindTask(NULL), c);
43 c->signal = AllocSignal(-1);
45 if (c->signal == -1) {
46 goto exit;
49 Signal(c->creator, SIGF_SINGLE);
51 while(TRUE) {
52 ULONG signals = Wait(SIGBREAKF_CTRL_C | (1UL << c->signal));
54 kprintf("MainLoop got a signal %lx\n", signals);
56 if (signals & SIGBREAKF_CTRL_C) {
57 break;
60 if (signals & (1UL << c->signal)) {
61 struct WatchData* w;
63 // dbus_connection_ref(c->connection);
65 kprintf("Checking watches\n");
66 for(w = (struct WatchData*) c->watches.mlh_Head;
67 w->node.mln_Succ != NULL;
68 w = (struct WatchData*) w->node.mln_Succ) {
69 kprintf("%s watch on fd %ld, flags %lx\n",
70 w->enabled ? "Enabled" : "Disabled",
71 dbus_watch_get_fd(w->watch), dbus_watch_get_flags(w->watch));
72 if (w->enabled) {
73 dbus_watch_handle(w->watch, dbus_watch_get_flags(w->watch));
77 kprintf("Dispatching messages\n");
78 /* Dispatch messages */
79 while (dbus_connection_dispatch(c->connection) == DBUS_DISPATCH_DATA_REMAINS) {
80 kprintf("More messages available\n");
83 // dbus_connection_unref(c->connection);
87 exit:
88 c->main = NULL;
89 Signal(c->creator, SIGF_SINGLE);
90 kprintf("MainLoop terminating\n");
93 static void* CreateWatchData(DBusWatch* watch) {
94 struct WatchData* w = AllocVec(sizeof(struct WatchData), MEMF_ANY|MEMF_CLEAR);
96 if (w != NULL) {
97 w->enabled = dbus_watch_get_enabled(watch);
98 w->watch = watch;
101 return w;
105 static void DeleteWatchData(void* memory) {
106 struct WatchData* w = (struct WatchData*) memory;
108 if (w != NULL) {
109 if (w->node.mln_Succ != NULL) {
110 Remove((struct Node*) w);
113 FreeVec(w);
117 static void* CreateConnectionData(DBusConnection* connection) {
118 struct ConnectionData* c = AllocVec(sizeof(struct ConnectionData), MEMF_ANY|MEMF_CLEAR);
120 kprintf("CreateConnectionData %08lx\n", c);
122 if (c != NULL) {
123 c->connection = connection;
124 c->creator = FindTask(NULL);
125 NewList((struct List*) &c->watches);
127 Forbid();
128 kprintf("creating mainloop\n");
129 c->main = (struct Task*) CreateNewProcTags(NP_Entry, (ULONG) MainLoop,
130 NP_Name, (ULONG) "dbus.library main loop",
131 NP_Priority, 0,
132 TAG_DONE);
133 kprintf("created mainloop %08lx\n", c->main);
134 if (c->main != NULL) {
135 c->main->tc_UserData = c;
138 SetSignal(0, SIGF_SINGLE);
139 Permit();
141 Wait(SIGF_SINGLE);
143 if (c->main == NULL) {
144 DeleteConnectionData(c);
145 c = NULL;
149 return c;
153 static void DeleteConnectionData(struct ConnectionData* c) {
154 kprintf("DeleteConnectionData %08lx\n", c);
156 if (c != NULL) {
157 if (c->main != NULL) {
158 SetSignal(0, SIGF_SINGLE);
159 Signal(c->main, SIGBREAKF_CTRL_C);
160 Wait(SIGF_SINGLE);
163 FreeVec(c);
167 static dbus_bool_t AddWatchFunction(DBusWatch* watch,
168 void* data) {
169 struct ConnectionData* c = (struct ConnectionData*) data;
170 struct WatchData* w;
172 kprintf("AddWatchFunction\n");
174 w = CreateWatchData(watch);
176 if (w == NULL) {
177 return FALSE;
180 AddTail((struct List*) &c->watches, (struct Node*) w);
181 dbus_watch_set_data(watch, w, NULL);
183 return TRUE;
186 static void WatchToggledFunction(DBusWatch* watch,
187 void* data) {
188 struct ConnectionData* c = (struct ConnectionData*) data;
189 struct WatchData* w = (struct WatchData*) dbus_watch_get_data(watch);
191 kprintf("WatchToggledFunction %lx\n", w);
193 w->enabled = dbus_watch_get_enabled(watch);
196 static void RemoveWatchFunction(DBusWatch* watch,
197 void* data) {
198 struct ConnectionData* c = (struct ConnectionData*) data;
199 struct WatchData* w = (struct WatchData*) dbus_watch_get_data(watch);
201 kprintf("RemoveWatchFunction %lx\n", w);
203 dbus_watch_set_data(watch, NULL, NULL);
204 DeleteWatchData(w);
207 static dbus_bool_t AddTimeoutFunction(DBusTimeout* timeout,
208 void* data) {
209 struct ConnectionData* c = (struct ConnectionData*) data;
211 kprintf("AddTimeoutFunction\n");
212 return TRUE;
215 static void TimeoutToggledFunction(DBusTimeout* timeout,
216 void* data) {
217 struct ConnectionData* c = (struct ConnectionData*) data;
219 kprintf("TimeoutToggledFunction\n");
222 static void RemoveTimeoutFunction(DBusTimeout* timeout,
223 void* data) {
224 struct ConnectionData* c = (struct ConnectionData*) data;
226 kprintf("RemoveTimeoutFunction\n");
230 static void DispatchStatusFunction(DBusConnection* connection,
231 DBusDispatchStatus new_status,
232 void* data) {
233 struct ConnectionData* c = (struct ConnectionData*) data;
235 kprintf("DispatchStatusFunction %d\n", new_status);
237 if (new_status == DBUS_DISPATCH_DATA_REMAINS) {
238 Signal(c->main, 1UL << c->signal);
242 static void WakeupMainFunction(void* data) {
243 struct ConnectionData* c = (struct ConnectionData*) data;
245 kprintf("WakeupMainFunction\n");
246 Signal(c->main, 1UL << c->signal);
249 dbus_bool_t dbus_a_setup_connection(DBusConnection* connection) {
250 struct ConnectionData* c;
252 c = CreateConnectionData(connection);
254 if (c != NULL) {
255 dbus_connection_set_watch_functions(connection,
256 AddWatchFunction,
257 RemoveWatchFunction,
258 WatchToggledFunction,
259 c, NULL);
261 dbus_connection_set_timeout_functions(connection,
262 AddTimeoutFunction,
263 RemoveTimeoutFunction,
264 TimeoutToggledFunction,
265 c, NULL);
267 dbus_connection_set_dispatch_status_function(connection, DispatchStatusFunction,
268 c, NULL);
270 dbus_connection_set_wakeup_main_function(connection, WakeupMainFunction,
271 c, NULL);
273 kprintf("Slot A: %ld\n", Slot);
274 if (dbus_connection_allocate_data_slot(&Slot)) {
275 kprintf("Slot B: %ld\n", Slot);
276 if (dbus_connection_set_data(connection, Slot, c, DeleteConnectionData)) {
277 kprintf("Slot C: %ld\n", Slot);
278 return TRUE;
283 DeleteConnectionData(c);
284 return FALSE;
287 void dbus_a_cleanup_connection(DBusConnection* connection) {
288 struct ConnectionData* c;
290 kprintf("CleanupAmigaConnection\n");
292 kprintf("Slot X: %ld\n", Slot);
293 c = dbus_connection_get_data(connection, Slot);
295 if (c != NULL) {
296 dbus_connection_set_data(connection, Slot, NULL, NULL);
297 dbus_connection_free_data_slot(&Slot);
298 kprintf("Slot Y: %ld\n", Slot);
301 dbus_connection_set_dispatch_status_function(connection, NULL, NULL, NULL);
302 dbus_connection_set_wakeup_main_function(connection, NULL, NULL, NULL);
303 dbus_connection_set_watch_functions(connection, NULL, NULL, NULL, NULL, NULL);
304 dbus_connection_set_timeout_functions(connection, NULL, NULL, NULL, NULL, NULL);
306 kprintf("Slot X: %ld\n", Slot);