Additional callerid [change in Protocol]
uwesmail2005-lkml at yahoo.de
uwesmail2005-lkml at yahoo.de
Thu Oct 26 09:20:37 PDT 2006
I want that this goes into dbus before 1.0:
The header should contain an additional callerid value. That should be
0 by default. Only the binary protocol is affected.
How it should be used:
After 1.0 or (if the API could change for this,) before, there would be
a DBusMainloop data struct and a DBusWakeup struct. Like
struct DBusMainloop{
int done;
DBusMainloop*parent;
DBusWakeup*queue;
};
struct DBusWakeup{
DBusWakeup*next;
void(*prepare)(DBusWakeup*This,DBusMainloop*caller,void*data);
void(*dispatch)(DBusWakeup*This,DBusMainloop*caller,void*data);
enum{TIMER,FD_RD,FD_WR,...}type;
void*free;
};
struct data{
fd_set*set; //deliberately first member
int* max_plus_1;
};
The idea is that DBus gives a generic mainloop implementation to all
its
users.
Every user defines a DBusWakeup where it sets the prepare and dispatch
members, and links it into the queue. The mainloop executes
while(!done)
and calls all DBusWakeup.prepare members, where a
timer wakeup (if it has a timeout to set) allocates some timespec
memory
(if free is NULL or recycles that if not) and sets the timespec* that
(timespec**)data points to to its address. Otherwise it leaves that
alone,
but frees the free member. A file (or socket) wakeup in prepare only
FD_SET the fd in the set member of the data struct that data points to
and maxes in fd+1 into the max_plus_1 member of that data struct.
(The int that this points to)
After that the select (or WaitForMultiple/GetMessage(?) on Windows).
After that the dispatch functions are called. The timer functions must
free the free member and do their work, the file functions
FD_ISSET in (fd_set**)data and if set read or write.
End of loop body. Start over again.
Nothing in the mainloop does dbus_dispatch. Nothing in the mainloop is
about D-Bus. For that the DBusConnection should be derived from(that
means contain as its first member) DBusWakeup type FD_RD_WR|FD_EXC. In
its prepare it will set a dispatching flag and set a member to caller.
Then it will dbus_dispatch until COMPLETE.
Then it will reset that flag (and possibly the member to NULL) and do a
normal prepare for read (and write if the sendqueue is full). That
dispatching in prepare won't be done if caller->parent is set.
Blocking calls: They allocate a new DBusMainloop, set its parent to the
saved caller and its queue from the parent, set the callerid to the
serial or callerid (if that was set) that the dbus_dispatch has
(hopefully) set in the DBusConnection and do a mainloop call. Now the
dispatch function queues all messages that don't have the callerid into
the parent, every call will be dispatched, and the return will set the
done flag in the new DBusMainloop. After the return from the mainloop,
the parent will be saved again (because it could be overwritten by
another blocking call) in the DBusConnection, the DBusMainloop freed
and the blocking call is over.
Such a blocking call can't deadlock even over many processes. And I
think
that such a mainloop is easier to integrate with other librarys that
want
to use a mainloop too. (If they do it along the same lines)
___________________________________________________________
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de
More information about the dbus
mailing list