2003-09-05 22:59:58 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include "io_internal.h"
|
|
|
|
|
2012-04-10 21:15:51 +00:00
|
|
|
void io_wantwrite_really(int64 d, io_entry* e);
|
|
|
|
|
2003-09-05 22:59:58 +00:00
|
|
|
int64 io_canwrite() {
|
|
|
|
io_entry* e;
|
2016-10-04 21:31:14 +00:00
|
|
|
|
|
|
|
#if defined(HAVE_SIGIO)
|
|
|
|
/* We promise that the user can call io_canread() and read, and
|
|
|
|
* the user uses io_tryread or calls io_eagain_read to signal if
|
|
|
|
* there is no more data to read. That means if the user does not
|
|
|
|
* call io_eagain_read, we need to know which fd it was so we can
|
|
|
|
* keep it in the alternative queue. */
|
|
|
|
if (alt_curwrite!=-1) {
|
|
|
|
e=iarray_get(&io_fds,alt_curwrite);
|
|
|
|
e->next_write=alt_firstwrite;
|
|
|
|
alt_firstwrite=alt_curwrite;
|
|
|
|
alt_curwrite=-1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-09-12 22:03:51 +00:00
|
|
|
if (first_writeable==-1)
|
2014-08-28 19:03:57 +00:00
|
|
|
#if defined(HAVE_SIGIO)
|
2003-09-12 22:03:51 +00:00
|
|
|
{
|
2014-04-04 18:11:03 +00:00
|
|
|
if (alt_firstwrite>=0 && (e=iarray_get(&io_fds,alt_firstwrite)) && e->canwrite) {
|
2003-09-12 22:03:51 +00:00
|
|
|
debug_printf(("io_canwrite: normal write queue is empty, swapping in alt write queue (starting with %ld)\n",alt_firstwrite));
|
|
|
|
first_writeable=alt_firstwrite;
|
|
|
|
alt_firstwrite=-1;
|
|
|
|
} else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
for (;;) {
|
|
|
|
int64 r;
|
2014-04-04 18:11:03 +00:00
|
|
|
e=iarray_get(&io_fds,first_writeable);
|
2003-09-12 22:03:51 +00:00
|
|
|
if (!e) break;
|
|
|
|
r=first_writeable;
|
2003-09-05 22:59:58 +00:00
|
|
|
first_writeable=e->next_write;
|
2003-11-28 17:38:08 +00:00
|
|
|
e->next_write=-1;
|
2016-10-04 20:38:04 +00:00
|
|
|
|
|
|
|
if (e->closed) {
|
|
|
|
/* The fd was previously closed, but there were still open events on it.
|
|
|
|
* To prevent race conditions, we did not actually close the fd
|
|
|
|
* but only marked it as closed, so we can skip this event here
|
|
|
|
* and really closed it now. */
|
|
|
|
io_close(r);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2003-09-12 22:03:51 +00:00
|
|
|
debug_printf(("io_canwrite: dequeue %lld from normal write queue (next is %ld)\n",r,first_writeable));
|
2005-09-09 22:12:23 +00:00
|
|
|
if (e->wantwrite &&
|
|
|
|
#ifdef __MINGW32__
|
|
|
|
(e->canwrite || e->sendfilequeued==1)
|
|
|
|
#else
|
|
|
|
e->canwrite
|
|
|
|
#endif
|
|
|
|
) {
|
2014-08-28 19:03:57 +00:00
|
|
|
#if defined(HAVE_SIGIO)
|
2016-10-04 21:31:14 +00:00
|
|
|
#if 0
|
|
|
|
/* this code violates an invariant that the other code has, namely
|
|
|
|
* that e->next_read is -1 once the fd is dequeued. */
|
2003-09-12 22:03:51 +00:00
|
|
|
e->next_write=alt_firstwrite;
|
|
|
|
alt_firstwrite=r;
|
|
|
|
debug_printf(("io_canwrite: enqueue %ld in alt write queue (next is %ld)\n",alt_firstwrite,e->next_write));
|
2016-10-04 21:31:14 +00:00
|
|
|
#else
|
|
|
|
alt_curwrite=r;
|
|
|
|
#endif
|
2003-10-21 12:40:41 +00:00
|
|
|
if (io_waitmode!=_SIGIO)
|
2003-10-22 12:52:40 +00:00
|
|
|
#endif
|
2003-10-21 12:37:49 +00:00
|
|
|
e->canwrite=0;
|
2012-04-10 21:15:51 +00:00
|
|
|
if (!e->kernelwantwrite)
|
|
|
|
io_wantwrite_really(r,e);
|
2003-09-12 22:03:51 +00:00
|
|
|
return r;
|
|
|
|
}
|
2003-09-05 22:59:58 +00:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|