_dbus_write/read/poll etc and regular files

Havoc Pennington hp@redhat.com
Mon Jan 17 09:26:17 PST 2005


On Mon, 2005-01-17 at 14:17 +0000, Tor Lillqvist wrote:
> How important is it that _dbus_write(), _dbus_poll() etc can be used
> also for file descriptors referring regular files, not just sockets?
> 
> If I have read the current code in CVS correctly, the only use case
> with non-sockets is the writing of the message bus address and process
> pid in bus_context_new() and _dbus_become_daemon() when called from
> bus/main.c:main(). Would it be better to use "normal" write(), or even
> printf() instead for this?

I think it would be fine to do as you suggest, though I'd propose that
we rename to _dbus_socket_write(), _dbus_socket_poll() etc. in this
case ... maybe even make it typesafe/opaque:
 typedef struct
 {
   int value;
 } DBusSocketHandle;

 dbus_bool_t _dbus_socket_handle_invalid (DBusSocketHandle *handle)  
 { return handle->value < 0; }

that sort of thing. I don't know if that's worth it but it might keep
people from introducing code that breaks win32 since you wouldn't be
able to get a SocketHandle from a file. 

> The reason is that on Win32, file descriptors (the stuff returned by
> open(), fileno() etc) are local to the C library. WinSock sockets
> don't have anything to do with C library file descriptors. This can be
> a bit of a problem in porting Unix code that assumes sockets are file
> descriptors, they can all be select()ed, etc.

Another approach maybe is:
 typedef struct
 {
   DBusStreamType type; /* DBUS_STREAM_SOCKET, DBUS_STREAM_FILE, etc. */
   int value;
 } DBusStream;

And have _dbus_poll (or _dbus_wait_for_multiple_streams()) take one of
those instead of just an fd... then in the win32 implementation could
you unpack which descriptors are files and which are sockets, and
construct a WaitForMultipleObjects() call that can wait on both at once?

I don't know if all this abstraction is worth it though if right now we
are pretty much always using sockets. Why not just take any usage of fds
with files and wrap it in specialized functions inside dbus-sysdeps that
use write() or whatever directly, and then declare that the exported fd-
handling functions are sockets only - maybe rename them with "socket" in
the name.

> To get past this, I have added a "wrapper" or "encapsulation" layer in
> dbus-sysdeps.c so that one can encapsulate either a C library file
> descriptor or WinSock socket, and get back a D-BUS-private "pseudo"
> file descriptor, which then is passed to _dbus_write()
> etc. _dbus_write() then either uses write() or send(). _dbus_read()
> either read() or recv(). _dbus_poll() works only for sockets.
> 
> But it would be simpler if I would know that only sockets need to be
> handled, this extra layer could then be dropped.

Ah, I guess you've already done some of the abstraction. My main
suggestion would be that if you do the abstraction work, make it a
little bit higher level (e.g. create a stream object or something,
adjust the API of poll(), whatever, so it's really abstracting things
rather than wedging it all into the UNIX API).

> Once I have everything compiling and dbus-test and bus-test working
> again after Havoc's recent commits, I'll put up diffs for people to
> check.

I realized this morning that yesterday's changes probably hosed you
pretty badly, sorry about that, I wasn't thinking.

Havoc




More information about the dbus mailing list