server: Create a separate fd object for each mailslot writer. Make them first-class file handles.
This commit is contained in:
parent
7c434992d6
commit
72ff2bf363
|
@ -56,7 +56,7 @@ struct mailslot
|
|||
{
|
||||
struct object obj;
|
||||
struct fd *fd;
|
||||
struct fd *write_fd;
|
||||
int write_fd;
|
||||
unsigned int max_msgsize;
|
||||
int read_timeout;
|
||||
struct list writers;
|
||||
|
@ -105,6 +105,7 @@ static const struct fd_ops mailslot_fd_ops =
|
|||
struct mail_writer
|
||||
{
|
||||
struct object obj;
|
||||
struct fd *fd;
|
||||
struct mailslot *mailslot;
|
||||
struct list entry;
|
||||
unsigned int access;
|
||||
|
@ -137,12 +138,13 @@ static enum server_fd_type mail_writer_get_fd_type( struct fd *fd );
|
|||
|
||||
static const struct fd_ops mail_writer_fd_ops =
|
||||
{
|
||||
NULL, /* get_poll_events */
|
||||
NULL, /* poll_event */
|
||||
default_fd_get_poll_events, /* get_poll_events */
|
||||
default_poll_event, /* poll_event */
|
||||
no_flush, /* flush */
|
||||
mail_writer_get_fd_type, /* get_fd_type */
|
||||
no_queue_async, /* queue_async */
|
||||
NULL /* cancel_async */
|
||||
default_fd_queue_async, /* queue_async */
|
||||
default_fd_reselect_async, /* reselect_async */
|
||||
default_fd_cancel_async /* cancel_async */
|
||||
};
|
||||
|
||||
|
||||
|
@ -195,11 +197,13 @@ static void mailslot_destroy( struct object *obj)
|
|||
struct mailslot *mailslot = (struct mailslot *) obj;
|
||||
|
||||
assert( mailslot->fd );
|
||||
assert( mailslot->write_fd );
|
||||
|
||||
shutdown( get_unix_fd( mailslot->fd ), SHUT_RDWR );
|
||||
if (mailslot->write_fd != -1)
|
||||
{
|
||||
shutdown( mailslot->write_fd, SHUT_RDWR );
|
||||
close( mailslot->write_fd );
|
||||
}
|
||||
release_object( mailslot->fd );
|
||||
release_object( mailslot->write_fd );
|
||||
}
|
||||
|
||||
static void mailslot_dump( struct object *obj, int verbose )
|
||||
|
@ -236,6 +240,7 @@ static struct object *mailslot_open_file( struct object *obj, unsigned int acces
|
|||
{
|
||||
struct mailslot *mailslot = (struct mailslot *)obj;
|
||||
struct mail_writer *writer;
|
||||
int unix_fd;
|
||||
|
||||
if (!(sharing & FILE_SHARE_READ))
|
||||
{
|
||||
|
@ -258,13 +263,27 @@ static struct object *mailslot_open_file( struct object *obj, unsigned int acces
|
|||
}
|
||||
}
|
||||
|
||||
if (!(writer = alloc_object( &mail_writer_ops ))) return NULL;
|
||||
if ((unix_fd = dup( mailslot->write_fd )) == -1)
|
||||
{
|
||||
file_set_error();
|
||||
return NULL;
|
||||
}
|
||||
if (!(writer = alloc_object( &mail_writer_ops )))
|
||||
{
|
||||
close( unix_fd );
|
||||
return NULL;
|
||||
}
|
||||
grab_object( mailslot );
|
||||
writer->mailslot = mailslot;
|
||||
writer->access = mail_writer_map_access( &writer->obj, access );
|
||||
writer->sharing = sharing;
|
||||
|
||||
list_add_head( &mailslot->writers, &writer->entry );
|
||||
|
||||
if (!(writer->fd = create_anonymous_fd( &mail_writer_fd_ops, unix_fd, &writer->obj, options )))
|
||||
{
|
||||
release_object( writer );
|
||||
return NULL;
|
||||
}
|
||||
return &writer->obj;
|
||||
}
|
||||
|
||||
|
@ -396,7 +415,7 @@ static struct mailslot *create_mailslot( struct directory *root,
|
|||
if (!mailslot) return NULL;
|
||||
|
||||
mailslot->fd = NULL;
|
||||
mailslot->write_fd = NULL;
|
||||
mailslot->write_fd = -1;
|
||||
mailslot->max_msgsize = max_msgsize;
|
||||
mailslot->read_timeout = read_timeout;
|
||||
list_init( &mailslot->writers );
|
||||
|
@ -406,11 +425,10 @@ static struct mailslot *create_mailslot( struct directory *root,
|
|||
fcntl( fds[0], F_SETFL, O_NONBLOCK );
|
||||
fcntl( fds[1], F_SETFL, O_NONBLOCK );
|
||||
shutdown( fds[0], SHUT_RD );
|
||||
mailslot->write_fd = fds[0];
|
||||
mailslot->fd = create_anonymous_fd( &mailslot_fd_ops, fds[1], &mailslot->obj,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
mailslot->write_fd = create_anonymous_fd( &mail_writer_fd_ops, fds[0], &mailslot->obj,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
if (mailslot->fd && mailslot->write_fd) return mailslot;
|
||||
if (mailslot->fd) return mailslot;
|
||||
}
|
||||
else file_set_error();
|
||||
|
||||
|
@ -427,6 +445,7 @@ static void mail_writer_destroy( struct object *obj)
|
|||
{
|
||||
struct mail_writer *writer = (struct mail_writer *) obj;
|
||||
|
||||
if (writer->fd) release_object( writer->fd );
|
||||
list_remove( &writer->entry );
|
||||
release_object( writer->mailslot );
|
||||
}
|
||||
|
@ -439,8 +458,7 @@ static enum server_fd_type mail_writer_get_fd_type( struct fd *fd )
|
|||
static struct fd *mail_writer_get_fd( struct object *obj )
|
||||
{
|
||||
struct mail_writer *writer = (struct mail_writer *) obj;
|
||||
|
||||
return (struct fd *)grab_object( writer->mailslot->write_fd );
|
||||
return (struct fd *)grab_object( writer->fd );
|
||||
}
|
||||
|
||||
static unsigned int mail_writer_map_access( struct object *obj, unsigned int access )
|
||||
|
|
Loading…
Reference in New Issue