From: William T. M. <wt...@du...> - 2002-11-11 02:18:29
|
On Sun, Nov 10, 2002 at 03:39:16PM -0500, Ethan Blanton wrote: > > I'm not sure precisely what read/write while loops you're speaking of, > but we *really* need to avoid I/O requiring synchronicity (yes, that's What I meant is that the I/O handlers that actually call read() and write() on sockets will need to be moved out of the generic ft.c and into the prpls. This means more work for the prpls but a simpler interface. > a word) wherever possible. If a read or write fails to complete 100% > (i.e. you wanted a 2k packet and you only got 1k of it), you need to > mark this down someplace and hand control back to gaim until your > socket comes up as readable again. forcing synchronicity is where we > get the lags we have in the UI ... most (if not all) of our sockets > are actually nonblocking, we just force blocking behavior in places. I agree with your point in general, although I think if you look at the FT code in particular you will find that it is nicely asynchronous. :) > This may mean that prpls need to keep track of more state on a > per-connection or per-socket basis, but it's worth the effort... OK, here's my shot at a new interface. What follows is the part visible to the prpls (i.e. this goes in prpl.h). This is somewhat different from the current API, but I want to get it right this time; comments are welcome. ====== /* A struct, opaque to the prpls, that uniquely identifies * a file transfer session (a session consists of sending * one or more files to a given user). */ struct file_transfer; /* Functions called by the prpls */ /* ----------------------------- */ /* Set up an incoming session; this will prompt the user whether to * accept the transfer, where to put the files, etc. */ extern struct file_transfer *file_transfer_in_add(struct gaim_connection *gc, const char *who, const char *name, long totsize, long totfiles, const char *msg); /* Set up an outgoing session; this will prompt the user for which * file(s) to send. */ extern struct file_transfer *file_transfer_out_add(struct gaim_connection *gc, const char *who); /* For outgoing transfers, this is called before sending each file * to get the filename and size; and to set the offset for resuming. * For incoming transfers, this is called before receiving each file * to set the filename and size; and to get the offset for resuming. * Also opens the file for reading/writing as appropriate. */ extern int file_transfer_start_file(struct file_transfer *xfer, char **filename, long *size, long *offset); /* Read or write a chunk of data. For incoming transfers, * reads from buf and writes to a file; for outgoing transfers, * reads from a file and writes to buf. */ extern int file_transfer_do_chunk(struct file_transfer *xfer, char *buf, int len); /* This is used to get information about a session. */ extern int file_transfer_get_info(struct file_transfer *xfer, char **name, long *totfiles, long *totsize); /* Abort a session in progress. */ extern int file_transfer_abort(struct file_transfer *xfer, const char *why); /* Callbacks that each prpl should provide */ /* --------------------------------------- */ struct prpl { /* ... */ /* A session was successfully set up; the prpl may begin sending * or receiving the first file. */ void (* file_transfer_added) (struct gaim_connection *gc, struct file_transfer *xfer); /* A session was canceled by the user; the prpl should clean up. */ void (* file_transfer_canceled) (struct gaim_connection *gc, struct file_transfer *xfer); }; -- Wil |