Moved all references to file descriptors out of the generic object
structure.
Changed the poll()-related routines to deal with file descriptors
instead of objects and integrated poll support into fd.c.
diff --git a/server/sock.c b/server/sock.c
index 44e0088..51d7ec7 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -65,11 +65,13 @@
struct sock
{
struct object obj; /* object header */
+ struct fd *fd; /* socket file descriptor */
unsigned int state; /* status bits */
unsigned int mask; /* event mask */
unsigned int hmask; /* held (blocked) events */
unsigned int pmask; /* pending events */
unsigned int flags; /* socket flags */
+ int polling; /* is socket being polled? */
unsigned short type; /* socket type */
unsigned short family; /* socket family */
struct event *event; /* event object */
@@ -84,6 +86,7 @@
static void sock_dump( struct object *obj, int verbose );
static int sock_signaled( struct object *obj, struct thread *thread );
+static struct fd *sock_get_fd( struct object *obj );
static void sock_destroy( struct object *obj );
static int sock_get_poll_events( struct fd *fd );
@@ -102,7 +105,7 @@
remove_queue, /* remove_queue */
sock_signaled, /* signaled */
no_satisfied, /* satisfied */
- default_get_fd, /* get_fd */
+ sock_get_fd, /* get_fd */
sock_destroy /* destroy */
};
@@ -193,19 +196,20 @@
static int sock_reselect( struct sock *sock )
{
- int ev = sock_get_poll_events( sock->obj.fd_obj );
+ int ev = sock_get_poll_events( sock->fd );
if (debug_level)
fprintf(stderr,"sock_reselect(%p): new mask %x\n", sock, ev);
- if (sock->obj.select == -1) {
+ if (!sock->polling) /* FIXME: should find a better way to do this */
+ {
/* previously unconnected socket, is this reselect supposed to connect it? */
if (!(sock->state & ~FD_WINE_NONBLOCKING)) return 0;
/* ok, it is, attach it to the wineserver's main poll loop */
- add_select_user( &sock->obj );
+ sock->polling = 1;
}
/* update condition mask */
- set_select_events( &sock->obj, ev );
+ set_fd_events( sock->fd, ev );
return ev;
}
@@ -213,11 +217,11 @@
This function is used to signal pending events nevertheless */
static void sock_try_event ( struct sock *sock, int event )
{
- event = check_fd_events( sock->obj.fd_obj, event );
+ event = check_fd_events( sock->fd, event );
if (event)
{
if ( debug_level ) fprintf ( stderr, "sock_try_event: %x\n", event );
- sock_poll_event ( sock->obj.fd_obj, event );
+ sock_poll_event ( sock->fd, event );
}
}
@@ -413,7 +417,7 @@
{
if ( debug_level )
fprintf ( stderr, "removing socket %p from select loop\n", sock );
- set_select_events( &sock->obj, -1 );
+ set_fd_events( sock->fd, -1 );
}
else
sock_reselect( sock );
@@ -431,7 +435,7 @@
struct sock *sock = (struct sock *)obj;
assert( obj->ops == &sock_ops );
printf( "Socket fd=%p, state=%x, mask=%x, pending=%x, held=%x\n",
- sock->obj.fd_obj, sock->state,
+ sock->fd, sock->state,
sock->mask, sock->pmask, sock->hmask );
}
@@ -440,7 +444,7 @@
struct sock *sock = (struct sock *)obj;
assert( obj->ops == &sock_ops );
- return check_fd_events( sock->obj.fd_obj, sock_get_poll_events( sock->obj.fd_obj ) ) != 0;
+ return check_fd_events( sock->fd, sock_get_poll_events( sock->fd ) ) != 0;
}
static int sock_get_poll_events( struct fd *fd )
@@ -555,6 +559,12 @@
if ( pollev ) sock_try_event ( sock, pollev );
}
+static struct fd *sock_get_fd( struct object *obj )
+{
+ struct sock *sock = (struct sock *)obj;
+ return (struct fd *)grab_object( sock->fd );
+}
+
static void sock_destroy( struct object *obj )
{
struct sock *sock = (struct sock *)obj;
@@ -571,6 +581,7 @@
destroy_async_queue ( &sock->write_q );
}
if (sock->event) release_object( sock->event );
+ if (sock->fd) release_object( sock->fd );
}
/* create a new and unconnected socket */
@@ -587,12 +598,16 @@
return NULL;
}
fcntl(sockfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
- if (!(sock = alloc_fd_object( &sock_ops, &sock_fd_ops, -1 ))) return NULL;
- set_unix_fd( &sock->obj, sockfd );
+ if (!(sock = alloc_object( &sock_ops )))
+ {
+ close( sockfd );
+ return NULL;
+ }
sock->state = (type != SOCK_STREAM) ? (FD_READ|FD_WRITE) : 0;
sock->mask = 0;
sock->hmask = 0;
sock->pmask = 0;
+ sock->polling = 0;
sock->flags = flags;
sock->type = type;
sock->family = family;
@@ -601,6 +616,11 @@
sock->message = 0;
sock->wparam = 0;
sock->deferred = NULL;
+ if (!(sock->fd = alloc_fd( &sock_fd_ops, sockfd, &sock->obj )))
+ {
+ release_object( sock );
+ return NULL;
+ }
if (sock->flags & WSA_FLAG_OVERLAPPED)
{
init_async_queue (&sock->read_q);
@@ -635,14 +655,15 @@
* return.
*/
slen = sizeof(saddr);
- acceptfd = accept( get_unix_fd(sock->obj.fd_obj), &saddr, &slen);
+ acceptfd = accept( get_unix_fd(sock->fd), &saddr, &slen);
if (acceptfd==-1) {
sock_set_error();
release_object( sock );
return NULL;
}
- if (!(acceptsock = alloc_fd_object( &sock_ops, &sock_fd_ops, acceptfd )))
+ if (!(acceptsock = alloc_object( &sock_ops )))
{
+ close( acceptfd );
release_object( sock );
return NULL;
}
@@ -655,6 +676,7 @@
acceptsock->mask = sock->mask;
acceptsock->hmask = 0;
acceptsock->pmask = 0;
+ acceptsock->polling = 0;
acceptsock->type = sock->type;
acceptsock->family = sock->family;
acceptsock->event = NULL;
@@ -664,6 +686,12 @@
if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );
acceptsock->flags = sock->flags;
acceptsock->deferred = 0;
+ if (!(acceptsock->fd = alloc_fd( &sock_fd_ops, acceptfd, &acceptsock->obj )))
+ {
+ release_object( acceptsock );
+ release_object( sock );
+ return NULL;
+ }
if ( acceptsock->flags & WSA_FLAG_OVERLAPPED )
{
init_async_queue ( &acceptsock->read_q );