Started moving functions that deal with Unix file descriptors to a

separate fd object. This will be needed for file locking.
oldstable
Alexandre Julliard 2003-01-30 00:26:44 +00:00
parent 45adf0843f
commit 863637b158
31 changed files with 466 additions and 330 deletions

View File

@ -16,6 +16,7 @@ C_SRCS = \
debugger.c \
device.c \
event.c \
fd.c \
file.c \
handle.c \
hook.c \

View File

@ -147,34 +147,3 @@ void async_add_timeout(struct async *async, int timeout)
async->timeout = add_timeout_user( &async->when, async_callback, async );
}
}
DECL_HANDLER(register_async)
{
struct object *obj = get_handle_obj( current->process, req->handle, 0, NULL);
if ( !(obj) || !obj->ops->queue_async )
{
set_error(STATUS_INVALID_HANDLE);
return;
}
/*
* The queue_async method must do the following:
*
* 1. Get the async_queue for the request of given type.
* 2. Call find_async() to look for the specific client request in the queue (=> NULL if not found).
* 3. If status is STATUS_PENDING:
* a) If no async request found in step 2 (new request): call create_async() to initialize one.
* b) Set request's status to STATUS_PENDING.
* c) If the "queue" field of the async request is NULL: call async_insert() to put it into the queue.
* Otherwise:
* If the async request was found in step 2, destroy it by calling destroy_async().
* 4. Carry out any operations necessary to adjust the object's poll events
* Usually: set_elect_events (obj, obj->ops->get_poll_events()).
*
* See also the implementations in file.c, serial.c, and sock.c.
*/
obj->ops->queue_async (obj, req->overlapped, req->status, req->type, req->count);
release_object(obj);
}

View File

@ -71,12 +71,8 @@ static const struct object_ops atom_table_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satified */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
atom_table_destroy /* destroy */
};

View File

@ -46,12 +46,8 @@ static const struct object_ops change_ops =
remove_queue, /* remove_queue */
change_signaled, /* signaled */
no_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
no_destroy /* destroy */
};

View File

@ -51,12 +51,8 @@ static const struct object_ops console_input_ops =
remove_queue, /* remove_queue */
console_input_signaled, /* signaled */
no_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
console_get_file_info, /* get_file_info */
NULL, /* queue_async */
console_input_destroy /* destroy */
};
@ -80,12 +76,8 @@ static const struct object_ops console_input_events_ops =
remove_queue, /* remove_queue */
console_input_events_signaled, /* signaled */
no_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
console_input_events_destroy /* destroy */
};
@ -121,12 +113,8 @@ static const struct object_ops screen_buffer_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
console_get_file_info, /* get_file_info */
NULL, /* queue_async */
screen_buffer_destroy /* destroy */
};

View File

@ -72,12 +72,8 @@ static const struct object_ops debug_event_ops =
remove_queue, /* remove_queue */
debug_event_signaled, /* signaled */
no_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
debug_event_destroy /* destroy */
};
@ -93,12 +89,8 @@ static const struct object_ops debug_ctx_ops =
remove_queue, /* remove_queue */
debug_ctx_signaled, /* signaled */
no_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
debug_ctx_destroy /* destroy */
};

View File

@ -53,12 +53,8 @@ static const struct object_ops device_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
device_get_info, /* get_file_info */
NULL, /* queue_async */
no_destroy /* destroy */
};

View File

@ -50,12 +50,8 @@ static const struct object_ops event_ops =
remove_queue, /* remove_queue */
event_signaled, /* signaled */
event_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
no_destroy /* destroy */
};

244
server/fd.c 100644
View File

@ -0,0 +1,244 @@
/*
* Server-side file descriptor management
*
* Copyright (C) 2003 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "object.h"
#include "file.h"
#include "handle.h"
#include "process.h"
#include "request.h"
struct fd
{
struct object obj; /* object header */
const struct fd_ops *fd_ops; /* file descriptor operations */
struct object *user; /* object using this file descriptor */
int unix_fd; /* unix file descriptor */
int mode; /* file protection mode */
};
static void fd_dump( struct object *obj, int verbose );
static void fd_destroy( struct object *obj );
static const struct object_ops fd_ops =
{
sizeof(struct fd), /* size */
fd_dump, /* dump */
no_add_queue, /* add_queue */
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
default_get_fd, /* get_fd */
no_get_file_info, /* get_file_info */
fd_destroy /* destroy */
};
static void fd_dump( struct object *obj, int verbose )
{
struct fd *fd = (struct fd *)obj;
fprintf( stderr, "Fd unix_fd=%d mode=%06o user=%p\n", fd->unix_fd, fd->mode, fd->user );
}
static void fd_destroy( struct object *obj )
{
#if 0
struct fd *fd = (struct fd *)obj;
close( fd->unix_fd );
#endif
}
/* allocate an object that has an associated fd */
void *alloc_fd_object( const struct object_ops *ops,
const struct fd_ops *fd_user_ops, int unix_fd )
{
struct object *user;
struct fd *fd = alloc_object( &fd_ops, -1 );
if (!fd) return NULL;
if (!(user = alloc_object( ops, unix_fd )))
{
release_object( fd );
return NULL;
}
fd->fd_ops = fd_user_ops;
fd->user = user;
fd->unix_fd = unix_fd;
fd->mode = 0;
user->fd_obj = fd;
return user;
}
/* retrieve the unix fd for an object */
int get_unix_fd( struct object *obj )
{
struct fd *fd = obj->ops->get_fd( obj );
int unix_fd = -1;
if (fd)
{
unix_fd = fd->unix_fd;
release_object( fd );
}
return unix_fd;
}
/* set the unix fd for an object; can only be done once */
void set_unix_fd( struct object *obj, int unix_fd )
{
struct fd *fd = obj->fd_obj;
assert( fd );
assert( fd->unix_fd == -1 );
fd->unix_fd = unix_fd;
obj->fd = unix_fd;
}
/* close a file descriptor */
void close_fd( struct fd *fd )
{
release_object( fd );
}
/* callback for event happening in the main poll() loop */
void fd_poll_event( struct object *obj, int event )
{
struct fd *fd = obj->fd_obj;
return fd->fd_ops->poll_event( fd->user, event );
}
/* default add_queue() routine for objects that poll() on an fd */
int default_fd_add_queue( struct object *obj, struct wait_queue_entry *entry )
{
struct fd *fd = obj->fd_obj;
if (!obj->head) /* first on the queue */
set_select_events( obj, fd->fd_ops->get_poll_events( fd->user ) );
add_queue( obj, entry );
return 1;
}
/* default remove_queue() routine for objects that poll() on an fd */
void default_fd_remove_queue( struct object *obj, struct wait_queue_entry *entry )
{
grab_object( obj );
remove_queue( obj, entry );
if (!obj->head) /* last on the queue is gone */
set_select_events( obj, 0 );
release_object( obj );
}
/* default signaled() routine for objects that poll() on an fd */
int default_fd_signaled( struct object *obj, struct thread *thread )
{
struct fd *fd = obj->fd_obj;
int events = fd->fd_ops->get_poll_events( obj );
if (check_select_events( fd->unix_fd, events ))
{
/* stop waiting on select() if we are signaled */
set_select_events( obj, 0 );
return 1;
}
/* restart waiting on select() if we are no longer signaled */
if (obj->head) set_select_events( obj, events );
return 0;
}
/* default flush() routine */
int no_flush( struct object *obj )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
return 0;
}
/* default queue_async() routine */
void no_queue_async( struct object *obj, void* ptr, unsigned int status, int type, int count )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
}
/* same as get_handle_obj but retrieve the struct fd associated to the object */
static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handle,
unsigned int access )
{
struct fd *fd = NULL;
struct object *obj;
if ((obj = get_handle_obj( process, handle, 0, NULL )))
{
if (obj->fd_obj) fd = (struct fd *)grab_object( obj->fd_obj );
else set_error( STATUS_OBJECT_TYPE_MISMATCH );
release_object( obj );
}
return fd;
}
/* flush a file buffers */
DECL_HANDLER(flush_file)
{
struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
if (fd)
{
fd->fd_ops->flush( fd->user );
release_object( fd );
}
}
/* create / reschedule an async I/O */
DECL_HANDLER(register_async)
{
struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
/*
* The queue_async method must do the following:
*
* 1. Get the async_queue for the request of given type.
* 2. Call find_async() to look for the specific client request in the queue (=> NULL if not found).
* 3. If status is STATUS_PENDING:
* a) If no async request found in step 2 (new request): call create_async() to initialize one.
* b) Set request's status to STATUS_PENDING.
* c) If the "queue" field of the async request is NULL: call async_insert() to put it into the queue.
* Otherwise:
* If the async request was found in step 2, destroy it by calling destroy_async().
* 4. Carry out any operations necessary to adjust the object's poll events
* Usually: set_elect_events (obj, obj->ops->get_poll_events()).
*
* See also the implementations in file.c, serial.c, and sock.c.
*/
if (fd)
{
fd->fd_ops->queue_async( fd->user, req->overlapped, req->status, req->type, req->count );
release_object( fd );
}
}

View File

@ -40,6 +40,7 @@
#include "winerror.h"
#include "winbase.h"
#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@ -65,7 +66,6 @@ static struct file *file_hash[NAME_HASH_SIZE];
static void file_dump( struct object *obj, int verbose );
static int file_get_poll_events( struct object *obj );
static void file_poll_event( struct object *obj, int event );
static int file_get_fd( struct object *obj );
static int file_flush( struct object *obj );
static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void file_destroy( struct object *obj );
@ -75,19 +75,23 @@ static const struct object_ops file_ops =
{
sizeof(struct file), /* size */
file_dump, /* dump */
default_poll_add_queue, /* add_queue */
default_poll_remove_queue, /* remove_queue */
default_poll_signaled, /* signaled */
default_fd_add_queue, /* add_queue */
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
file_get_poll_events, /* get_poll_events */
file_poll_event, /* poll_event */
file_get_fd, /* get_fd */
file_flush, /* flush */
default_get_fd, /* get_fd */
file_get_info, /* get_file_info */
file_queue_async, /* queue_async */
file_destroy /* destroy */
};
static const struct fd_ops file_fd_ops =
{
file_get_poll_events, /* get_poll_events */
file_poll_event, /* poll_event */
file_flush, /* flush */
file_get_info, /* get_file_info */
file_queue_async /* queue_async */
};
static int get_name_hash( const char *name )
{
@ -127,7 +131,8 @@ static struct file *create_file_for_fd( int fd, unsigned int access, unsigned in
unsigned int attrs, int drive_type )
{
struct file *file;
if ((file = alloc_object( &file_ops, fd )))
if ((file = alloc_fd_object( &file_ops, &file_fd_ops, fd )))
{
file->name = NULL;
file->next = NULL;
@ -291,22 +296,10 @@ static void file_poll_event( struct object *obj, int event )
}
static int file_get_fd( struct object *obj )
{
struct file *file = (struct file *)obj;
assert( obj->ops == &file_ops );
return file->obj.fd;
}
static int file_flush( struct object *obj )
{
int ret;
struct file *file = (struct file *)grab_object(obj);
assert( obj->ops == &file_ops );
ret = (fsync( file->obj.fd ) != -1);
int ret = (fsync( get_unix_fd(obj) ) != -1);
if (!ret) file_set_error();
release_object( file );
return ret;
}
@ -314,17 +307,17 @@ static int file_get_info( struct object *obj, struct get_file_info_reply *reply,
{
struct stat st;
struct file *file = (struct file *)obj;
assert( obj->ops == &file_ops );
int unix_fd = get_unix_fd( obj );
if (reply)
{
if (fstat( file->obj.fd, &st ) == -1)
if (fstat( unix_fd, &st ) == -1)
{
file_set_error();
return FD_TYPE_INVALID;
}
if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) ||
S_ISSOCK(st.st_mode) || isatty(file->obj.fd)) reply->type = FILE_TYPE_CHAR;
S_ISSOCK(st.st_mode) || isatty(unix_fd)) reply->type = FILE_TYPE_CHAR;
else reply->type = FILE_TYPE_DISK;
if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
@ -394,7 +387,7 @@ static void file_queue_async(struct object *obj, void *ptr, unsigned int status,
async_insert( q, async );
/* Check if the new pending request can be served immediately */
pfd.fd = obj->fd;
pfd.fd = get_unix_fd( obj );
pfd.events = file_get_poll_events ( obj );
pfd.revents = 0;
poll ( &pfd, 1, 0 );
@ -469,7 +462,7 @@ static int set_file_pointer( obj_handle_t handle, unsigned int *low, int *high,
xto = *low+((off_t)*high<<32);
if (!(file = get_file_obj( current->process, handle, 0 )))
return 0;
if ((result = lseek(file->obj.fd,xto,whence))==-1)
if ((result = lseek( get_unix_fd(&file->obj), xto, whence))==-1)
{
/* Check for seek before start of file */
@ -492,13 +485,14 @@ static int set_file_pointer( obj_handle_t handle, unsigned int *low, int *high,
static int extend_file( struct file *file, off_t size )
{
static const char zero;
int unix_fd = get_unix_fd( &file->obj );
/* extend the file one byte beyond the requested size and then truncate it */
/* this should work around ftruncate implementations that can't extend files */
if ((lseek( file->obj.fd, size, SEEK_SET ) != -1) &&
(write( file->obj.fd, &zero, 1 ) != -1))
if ((lseek( unix_fd, size, SEEK_SET ) != -1) &&
(write( unix_fd, &zero, 1 ) != -1))
{
ftruncate( file->obj.fd, size );
ftruncate( unix_fd, size );
return 1;
}
file_set_error();
@ -509,16 +503,17 @@ static int extend_file( struct file *file, off_t size )
static int truncate_file( struct file *file )
{
int ret = 0;
off_t pos = lseek( file->obj.fd, 0, SEEK_CUR );
off_t eof = lseek( file->obj.fd, 0, SEEK_END );
int unix_fd = get_unix_fd( &file->obj );
off_t pos = lseek( unix_fd, 0, SEEK_CUR );
off_t eof = lseek( unix_fd, 0, SEEK_END );
if (eof < pos) ret = extend_file( file, pos );
else
{
if (ftruncate( file->obj.fd, pos ) != -1) ret = 1;
if (ftruncate( unix_fd, pos ) != -1) ret = 1;
else file_set_error();
}
lseek( file->obj.fd, pos, SEEK_SET ); /* restore file pos */
lseek( unix_fd, pos, SEEK_SET ); /* restore file pos */
return ret;
}
@ -527,17 +522,18 @@ int grow_file( struct file *file, int size_high, int size_low )
{
int ret = 0;
struct stat st;
int unix_fd = get_unix_fd( &file->obj );
off_t old_pos, size = size_low + (((off_t)size_high)<<32);
if (fstat( file->obj.fd, &st ) == -1)
if (fstat( unix_fd, &st ) == -1)
{
file_set_error();
return 0;
}
if (st.st_size >= size) return 1; /* already large enough */
old_pos = lseek( file->obj.fd, 0, SEEK_CUR ); /* save old pos */
old_pos = lseek( unix_fd, 0, SEEK_CUR ); /* save old pos */
ret = extend_file( file, size );
lseek( file->obj.fd, old_pos, SEEK_SET ); /* restore file pos */
lseek( unix_fd, old_pos, SEEK_SET ); /* restore file pos */
return ret;
}
@ -633,8 +629,8 @@ DECL_HANDLER(get_handle_fd)
if (fd != -1) reply->fd = fd;
else if (!get_error())
{
if ((fd = obj->ops->get_fd( obj )) != -1)
send_client_fd( current->process, fd, req->handle );
int unix_fd = get_unix_fd( obj );
if (unix_fd != -1) send_client_fd( current->process, unix_fd, req->handle );
}
reply->type = obj->ops->get_file_info( obj, NULL, &reply->flags );
release_object( obj );
@ -663,18 +659,6 @@ DECL_HANDLER(truncate_file)
}
}
/* flush a file buffers */
DECL_HANDLER(flush_file)
{
struct object *obj;
if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
{
obj->ops->flush( obj );
release_object( obj );
}
}
/* set a file access and modification times */
DECL_HANDLER(set_file_time)
{

56
server/file.h 100644
View File

@ -0,0 +1,56 @@
/*
* Server-side file definitions
*
* Copyright (C) 2003 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __WINE_SERVER_FILE_H
#define __WINE_SERVER_FILE_H
#include "object.h"
struct fd;
/* operations valid on file descriptor objects */
struct fd_ops
{
/* get the events we want to poll() for on this object */
int (*get_poll_events)(struct object *);
/* a poll() event occured */
void (*poll_event)(struct object *,int event);
/* flush the object buffers */
int (*flush)(struct object *);
/* get file information */
int (*get_file_info)(struct object *,struct get_file_info_reply *, int *flags);
/* queue an async operation - see register_async handler in async.c*/
void (*queue_async)(struct object *, void* ptr, unsigned int status, int type, int count);
};
extern void *alloc_fd_object( const struct object_ops *ops,
const struct fd_ops *fd_user_ops, int unix_fd );
extern int get_unix_fd( struct object *obj );
extern void set_unix_fd( struct object *obj, int unix_fd );
extern void close_fd( struct fd *fd );
extern void fd_poll_event( struct object *obj, int event );
extern int default_fd_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern void default_fd_remove_queue( struct object *obj, struct wait_queue_entry *entry );
extern int default_fd_signaled( struct object *obj, struct thread *thread );
extern int no_flush( struct object *obj );
extern void no_queue_async(struct object *obj, void* ptr, unsigned int status, int type, int count);
#endif /* __WINE_SERVER_FILE_H */

View File

@ -104,12 +104,8 @@ static const struct object_ops handle_table_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
handle_table_destroy /* destroy */
};

View File

@ -66,12 +66,8 @@ static const struct object_ops hook_table_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
hook_table_destroy /* destroy */
};

View File

@ -28,6 +28,7 @@
#include "winbase.h"
#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@ -47,7 +48,7 @@ struct mapping
struct mapping *shared_prev; /* prev in shared PE mapping list */
};
static int mapping_get_fd( struct object *obj );
static struct fd *mapping_get_fd( struct object *obj );
static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void mapping_dump( struct object *obj, int verbose );
static void mapping_destroy( struct object *obj );
@ -60,12 +61,8 @@ static const struct object_ops mapping_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
mapping_get_fd, /* get_fd */
no_flush, /* flush */
mapping_get_info, /* get_file_info */
NULL, /* queue_async */
mapping_destroy /* destroy */
};
@ -111,13 +108,7 @@ static void init_page_size(void)
/* get the fd to use for mmaping a file */
inline static int get_mmap_fd( struct file *file )
{
struct object *obj;
if (!(obj = (struct object *)file))
{
set_error( STATUS_INVALID_HANDLE );
return -1;
}
return obj->ops->get_fd( obj );
return get_unix_fd( (struct object *)file );
}
/* find the shared PE mapping for a given mapping */
@ -327,11 +318,12 @@ static void mapping_dump( struct object *obj, int verbose )
fputc( '\n', stderr );
}
static int mapping_get_fd( struct object *obj )
static struct fd *mapping_get_fd( struct object *obj )
{
struct mapping *mapping = (struct mapping *)obj;
assert( obj->ops == &mapping_ops );
return get_mmap_fd( mapping->file );
return default_get_fd( (struct object *)mapping->file );
}
static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )

View File

@ -54,12 +54,8 @@ static const struct object_ops mutex_ops =
remove_queue, /* remove_queue */
mutex_signaled, /* signaled */
mutex_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
mutex_destroy /* destroy */
};

View File

@ -38,6 +38,7 @@
#include "winbase.h"
#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@ -90,35 +91,35 @@ static const struct object_ops named_pipe_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
named_pipe_destroy /* destroy */
};
static void pipe_user_dump( struct object *obj, int verbose );
static void pipe_user_destroy( struct object *obj);
static int pipe_user_get_fd( struct object *obj );
static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static const struct object_ops pipe_user_ops =
{
sizeof(struct pipe_user), /* size */
pipe_user_dump, /* dump */
default_poll_add_queue, /* add_queue */
default_poll_remove_queue, /* remove_queue */
default_poll_signaled, /* signaled */
default_fd_add_queue, /* add_queue */
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
default_get_fd, /* get_fd */
pipe_user_get_info, /* get_file_info */
pipe_user_destroy /* destroy */
};
static const struct fd_ops pipe_user_fd_ops =
{
NULL, /* get_poll_events */
default_poll_event, /* poll_event */
pipe_user_get_fd, /* get_fd */
no_flush, /* flush */
pipe_user_get_info, /* get_file_info */
NULL, /* queue_async */
pipe_user_destroy /* destroy */
no_queue_async /* queue_async */
};
static void named_pipe_dump( struct object *obj, int verbose )
@ -192,13 +193,6 @@ static void pipe_user_destroy( struct object *obj)
release_object(user->pipe);
}
static int pipe_user_get_fd( struct object *obj )
{
struct pipe_user *user = (struct pipe_user *)obj;
assert( obj->ops == &pipe_user_ops );
return user->obj.fd;
}
static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
if (reply)
@ -243,7 +237,7 @@ static struct pipe_user *create_pipe_user( struct named_pipe *pipe, int fd )
{
struct pipe_user *user;
user = alloc_object( &pipe_user_ops, fd );
user = alloc_fd_object( &pipe_user_ops, &pipe_user_fd_ops, fd );
if(!user)
return NULL;
@ -475,4 +469,3 @@ DECL_HANDLER(get_named_pipe_info)
release_object(user);
}

View File

@ -28,6 +28,7 @@
#include <string.h>
#include <unistd.h>
#include "file.h"
#include "thread.h"
#include "unicode.h"
#include "list.h"
@ -137,6 +138,7 @@ void *alloc_object( const struct object_ops *ops, int fd )
if (obj)
{
obj->refcount = 1;
obj->fd_obj = NULL;
obj->fd = fd;
obj->select = -1;
obj->ops = ops;
@ -218,6 +220,7 @@ void release_object( void *ptr )
assert( !obj->head );
assert( !obj->tail );
obj->ops->destroy( obj );
if (obj->fd_obj) close_fd( obj->fd_obj );
if (obj->name) free_name( obj );
if (obj->select != -1) remove_select_user( obj );
if (obj->fd != -1) close( obj->fd );
@ -287,16 +290,17 @@ int no_satisfied( struct object *obj, struct thread *thread )
return 0; /* not abandoned */
}
int no_get_fd( struct object *obj )
struct fd *no_get_fd( struct object *obj )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
return -1;
return NULL;
}
int no_flush( struct object *obj )
struct fd *default_get_fd( struct object *obj )
{
if (obj->fd_obj) return (struct fd *)grab_object( obj->fd_obj );
set_error( STATUS_OBJECT_TYPE_MISMATCH );
return 0;
return NULL;
}
int no_get_file_info( struct object *obj, struct get_file_info_reply *info, int *flags )
@ -310,41 +314,6 @@ void no_destroy( struct object *obj )
{
}
/* default add_queue() routine for objects that poll() on an fd */
int default_poll_add_queue( struct object *obj, struct wait_queue_entry *entry )
{
if (!obj->head) /* first on the queue */
set_select_events( obj, obj->ops->get_poll_events( obj ) );
add_queue( obj, entry );
return 1;
}
/* default remove_queue() routine for objects that poll() on an fd */
void default_poll_remove_queue( struct object *obj, struct wait_queue_entry *entry )
{
grab_object(obj);
remove_queue( obj, entry );
if (!obj->head) /* last on the queue is gone */
set_select_events( obj, 0 );
release_object( obj );
}
/* default signaled() routine for objects that poll() on an fd */
int default_poll_signaled( struct object *obj, struct thread *thread )
{
int events = obj->ops->get_poll_events( obj );
if (check_select_events( obj->fd, events ))
{
/* stop waiting on select() if we are signaled */
set_select_events( obj, 0 );
return 1;
}
/* restart waiting on select() if we are no longer signaled */
if (obj->head) set_select_events( obj, events );
return 0;
}
/* default handler for poll() events */
void default_poll_event( struct object *obj, int event )
{

View File

@ -55,18 +55,10 @@ struct object_ops
int (*signaled)(struct object *,struct thread *);
/* wait satisfied; return 1 if abandoned */
int (*satisfied)(struct object *,struct thread *);
/* get the events we want to poll() for on this object */
int (*get_poll_events)(struct object *);
/* a poll() event occured */
void (*poll_event)(struct object *,int event);
/* return a Unix fd that can be used to read/write from the object */
int (*get_fd)(struct object *);
/* flush the object buffers */
int (*flush)(struct object *);
/* return an fd object that can be used to read/write from the object */
struct fd *(*get_fd)(struct object *);
/* get file information */
int (*get_file_info)(struct object *,struct get_file_info_reply *, int *flags);
/* queue an async operation - see register_async handler in async.c*/
void (*queue_async)(struct object *, void* ptr, unsigned int status, int type, int count);
/* destroy on refcount == 0 */
void (*destroy)(struct object *);
};
@ -74,6 +66,7 @@ struct object_ops
struct object
{
unsigned int refcount; /* reference count */
struct fd *fd_obj; /* file descriptor */
int fd; /* file descriptor */
int select; /* select() user id */
const struct object_ops *ops;
@ -107,13 +100,10 @@ extern void release_object( void *obj );
extern struct object *find_object( const struct namespace *namespace, const WCHAR *name, size_t len );
extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern int no_satisfied( struct object *obj, struct thread *thread );
extern int no_get_fd( struct object *obj );
extern int no_flush( struct object *obj );
extern struct fd *no_get_fd( struct object *obj );
extern struct fd *default_get_fd( struct object *obj );
extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info, int *flags );
extern void no_destroy( struct object *obj );
extern int default_poll_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern void default_poll_remove_queue( struct object *obj, struct wait_queue_entry *entry );
extern int default_poll_signaled( struct object *obj, struct thread *thread );
extern void default_poll_event( struct object *obj, int event );
#ifdef DEBUG_OBJECTS
extern void dump_objects(void);

View File

@ -32,6 +32,7 @@
#include "winbase.h"
#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@ -47,7 +48,7 @@ struct pipe
static void pipe_dump( struct object *obj, int verbose );
static int pipe_get_poll_events( struct object *obj );
static int pipe_get_fd( struct object *obj );
static struct fd *pipe_get_fd( struct object *obj );
static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void pipe_destroy( struct object *obj );
@ -55,17 +56,22 @@ static const struct object_ops pipe_ops =
{
sizeof(struct pipe), /* size */
pipe_dump, /* dump */
default_poll_add_queue, /* add_queue */
default_poll_remove_queue, /* remove_queue */
default_poll_signaled, /* signaled */
default_fd_add_queue, /* add_queue */
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
pipe_get_fd, /* get_fd */
pipe_get_info, /* get_file_info */
pipe_destroy /* destroy */
};
static const struct fd_ops pipe_fd_ops =
{
pipe_get_poll_events, /* get_poll_events */
default_poll_event, /* poll_event */
pipe_get_fd, /* get_fd */
no_flush, /* flush */
pipe_get_info, /* get_file_info */
NULL, /* queue_async */
pipe_destroy /* destroy */
no_queue_async /* queue_async */
};
@ -73,7 +79,7 @@ static struct pipe *create_pipe_side( int fd, int side )
{
struct pipe *pipe;
if ((pipe = alloc_object( &pipe_ops, fd )))
if ((pipe = alloc_fd_object( &pipe_ops, &pipe_fd_ops, fd )))
{
pipe->other = NULL;
pipe->side = side;
@ -123,7 +129,7 @@ static int pipe_get_poll_events( struct object *obj )
return (pipe->side == READ_SIDE) ? POLLIN : POLLOUT;
}
static int pipe_get_fd( struct object *obj )
static struct fd *pipe_get_fd( struct object *obj )
{
struct pipe *pipe = (struct pipe *)obj;
assert( obj->ops == &pipe_ops );
@ -131,9 +137,9 @@ static int pipe_get_fd( struct object *obj )
if (!pipe->other)
{
set_error( STATUS_PIPE_BROKEN );
return -1;
return NULL;
}
return pipe->obj.fd;
return (struct fd *)grab_object( pipe->obj.fd_obj );
}
static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )

View File

@ -36,6 +36,7 @@
#include "winbase.h"
#include "winnt.h"
#include "file.h"
#include "handle.h"
#include "process.h"
#include "thread.h"
@ -62,13 +63,18 @@ static const struct object_ops process_ops =
remove_queue, /* remove_queue */
process_signaled, /* signaled */
no_satisfied, /* satisfied */
no_get_fd, /* get_fd */
no_get_file_info, /* get_file_info */
process_destroy /* destroy */
};
static const struct fd_ops process_fd_ops =
{
NULL, /* get_poll_events */
process_poll_event, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
process_destroy /* destroy */
no_queue_async /* queue_async */
};
/* process startup info */
@ -102,12 +108,8 @@ static const struct object_ops startup_info_ops =
remove_queue, /* remove_queue */
startup_info_signaled, /* signaled */
no_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
startup_info_destroy /* destroy */
};
@ -190,7 +192,7 @@ struct thread *create_process( int fd )
struct thread *thread = NULL;
int request_pipe[2];
if (!(process = alloc_object( &process_ops, fd ))) goto error;
if (!(process = alloc_fd_object( &process_ops, &process_fd_ops, fd ))) goto error;
process->next = NULL;
process->prev = NULL;
process->parent = NULL;

View File

@ -143,12 +143,8 @@ static const struct object_ops msg_queue_ops =
msg_queue_remove_queue, /* remove_queue */
msg_queue_signaled, /* signaled */
msg_queue_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
msg_queue_destroy /* destroy */
};
@ -161,12 +157,8 @@ static const struct object_ops thread_input_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
thread_input_destroy /* destroy */
};

View File

@ -37,7 +37,9 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include "object.h"
#include "file.h"
#include "handle.h"
#include "request.h"
#include "unicode.h"
@ -166,12 +168,8 @@ static const struct object_ops key_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
key_destroy /* destroy */
};
@ -1452,7 +1450,7 @@ static void load_registry( struct key *key, obj_handle_t handle )
int fd;
if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL ))) return;
fd = dup(obj->ops->get_fd( obj ));
fd = dup( get_unix_fd( obj ) );
release_object( obj );
if (fd != -1)
{
@ -1547,7 +1545,7 @@ static void save_registry( struct key *key, obj_handle_t handle )
return;
}
if (!(obj = get_handle_obj( current->process, handle, GENERIC_WRITE, NULL ))) return;
fd = dup(obj->ops->get_fd( obj ));
fd = dup( get_unix_fd( obj ) );
release_object( obj );
if (fd != -1)
{

View File

@ -48,6 +48,7 @@
#include "wincon.h"
#include "wine/library.h"
#include "file.h"
#include "handle.h"
#include "thread.h"
#include "process.h"
@ -81,13 +82,18 @@ static const struct object_ops master_socket_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_get_fd, /* get_fd */
no_get_file_info, /* get_file_info */
no_destroy /* destroy */
};
static const struct fd_ops master_socket_fd_ops =
{
NULL, /* get_poll_events */
master_socket_poll_event, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
no_destroy /* destroy */
no_queue_async /* queue_async */
};
@ -670,7 +676,7 @@ static void acquire_lock(void)
chmod( server_socket_name, 0600 ); /* make sure no other user can connect */
if (listen( fd, 5 ) == -1) fatal_perror( "listen" );
if (!(master_socket = alloc_object( &master_socket_ops, fd )))
if (!(master_socket = alloc_fd_object( &master_socket_ops, &master_socket_fd_ops, fd )))
fatal_error( "out of memory\n" );
master_socket->timeout = NULL;
set_select_events( &master_socket->obj, POLLIN );

View File

@ -28,7 +28,7 @@
#include <sys/types.h>
#include <unistd.h>
#include "object.h"
#include "file.h"
#include "thread.h"
#include "process.h"
@ -301,7 +301,7 @@ void select_loop(void)
{
if (pollfd[i].revents)
{
poll_users[i]->ops->poll_event( poll_users[i], pollfd[i].revents );
fd_poll_event( poll_users[i], pollfd[i].revents );
if (!--ret) break;
}
}

View File

@ -50,12 +50,8 @@ static const struct object_ops semaphore_ops =
remove_queue, /* remove_queue */
semaphore_signaled, /* signaled */
semaphore_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
no_destroy /* destroy */
};

View File

@ -39,13 +39,13 @@
#include "winerror.h"
#include "winbase.h"
#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
#include "async.h"
static void serial_dump( struct object *obj, int verbose );
static int serial_get_fd( struct object *obj );
static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static int serial_get_poll_events( struct object *obj );
static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count);
@ -82,17 +82,22 @@ static const struct object_ops serial_ops =
{
sizeof(struct serial), /* size */
serial_dump, /* dump */
default_poll_add_queue, /* add_queue */
default_poll_remove_queue, /* remove_queue */
default_poll_signaled, /* signaled */
default_fd_add_queue, /* add_queue */
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
default_get_fd, /* get_fd */
serial_get_info, /* get_file_info */
destroy_serial /* destroy */
};
static const struct fd_ops serial_fd_ops =
{
serial_get_poll_events, /* get_poll_events */
serial_poll_event, /* poll_event */
serial_get_fd, /* get_fd */
serial_flush, /* flush */
serial_get_info, /* get_file_info */
serial_queue_async, /* queue_async */
destroy_serial /* destroy */
serial_queue_async /* queue_async */
};
static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access, int attributes )
@ -137,7 +142,7 @@ static struct serial *create_serial( const char *nameptr, size_t len, unsigned i
if(0>fcntl(fd, F_SETFL, 0))
perror("fcntl");
if ((serial = alloc_object( &serial_ops, fd )))
if ((serial = alloc_fd_object( &serial_ops, &serial_fd_ops, fd )))
{
serial->attrib = attributes;
serial->access = access;
@ -194,13 +199,6 @@ static int serial_get_poll_events( struct object *obj )
return events;
}
static int serial_get_fd( struct object *obj )
{
struct serial *serial = (struct serial *)obj;
assert( obj->ops == &serial_ops );
return serial->obj.fd;
}
static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
struct serial *serial = (struct serial *) obj;
@ -245,7 +243,7 @@ static void serial_poll_event(struct object *obj, int event)
if(IS_READY(serial->wait_q) && (POLLIN & event) )
async_notify(serial->wait_q.head,STATUS_ALERTED);
set_select_events(obj,obj->ops->get_poll_events(obj));
set_select_events( obj, serial_get_poll_events(obj) );
}
static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count)
@ -295,7 +293,7 @@ static void serial_queue_async(struct object *obj, void *ptr, unsigned int statu
}
/* Check if the new pending request can be served immediately */
pfd.fd = obj->fd;
pfd.fd = get_unix_fd( obj );
pfd.events = serial_get_poll_events ( obj );
pfd.revents = 0;
poll ( &pfd, 1, 0 );
@ -315,16 +313,11 @@ static void serial_queue_async(struct object *obj, void *ptr, unsigned int statu
static int serial_flush( struct object *obj )
{
int ret;
struct serial *serial = (struct serial *)grab_object(obj);
assert( obj->ops == &serial_ops );
/* MSDN says: If hFile is a handle to a communications device,
* the function only flushes the transmit buffer.
*/
ret = (tcflush( serial->obj.fd, TCOFLUSH ) != -1);
int ret = (tcflush( get_unix_fd(obj), TCOFLUSH ) != -1);
if (!ret) file_set_error();
release_object( serial );
return ret;
}

View File

@ -40,12 +40,12 @@
#include "winerror.h"
#include "winbase.h"
#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
static void smb_dump( struct object *obj, int verbose );
static int smb_get_fd( struct object *obj );
static int smb_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static int smb_get_poll_events( struct object *obj );
static void destroy_smb(struct object *obj);
@ -64,17 +64,22 @@ static const struct object_ops smb_ops =
{
sizeof(struct smb), /* size */
smb_dump, /* dump */
default_poll_add_queue, /* add_queue */
default_poll_remove_queue, /* remove_queue */
default_poll_signaled, /* signaled */
default_fd_add_queue, /* add_queue */
default_fd_remove_queue, /* remove_queue */
default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
default_get_fd, /* get_fd */
smb_get_info, /* get_file_info */
destroy_smb /* destroy */
};
static const struct fd_ops smb_fd_ops =
{
smb_get_poll_events, /* get_poll_events */
default_poll_event, /* poll_event */
smb_get_fd, /* get_fd */
no_flush, /* flush */
smb_get_info, /* get_file_info */
NULL, /* queue_async */
destroy_smb /* destroy */
no_queue_async /* queue_async */
};
static void destroy_smb( struct object *obj)
@ -108,13 +113,6 @@ static int smb_get_poll_events( struct object *obj )
return events;
}
static int smb_get_fd( struct object *obj )
{
struct smb *smb = (struct smb *)obj;
assert( obj->ops == &smb_ops );
return smb->obj.fd;
}
static int smb_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
/* struct smb *smb = (struct smb *) obj; */
@ -154,7 +152,7 @@ DECL_HANDLER(create_smb)
return;
}
smb = alloc_object( &smb_ops, fd );
smb = alloc_fd_object( &smb_ops, &smb_fd_ops, fd );
if (smb)
{
smb->tree_id = req->tree_id;

View File

@ -61,12 +61,8 @@ static const struct object_ops snapshot_ops =
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
snapshot_destroy /* destroy */
};

View File

@ -44,9 +44,10 @@
#include <time.h>
#include <unistd.h>
#include "winerror.h"
#include "winbase.h"
#include "process.h"
#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@ -83,7 +84,6 @@ static void sock_dump( struct object *obj, int verbose );
static int sock_signaled( struct object *obj, struct thread *thread );
static int sock_get_poll_events( struct object *obj );
static void sock_poll_event( struct object *obj, int event );
static int sock_get_fd( struct object *obj );
static int sock_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void sock_destroy( struct object *obj );
static int sock_get_error( int err );
@ -98,13 +98,18 @@ static const struct object_ops sock_ops =
remove_queue, /* remove_queue */
sock_signaled, /* signaled */
no_satisfied, /* satisfied */
default_get_fd, /* get_fd */
sock_get_info, /* get_file_info */
sock_destroy /* destroy */
};
static const struct fd_ops sock_fd_ops =
{
sock_get_poll_events, /* get_poll_events */
sock_poll_event, /* poll_event */
sock_get_fd, /* get_fd */
no_flush, /* flush */
sock_get_info, /* get_file_info */
sock_queue_async, /* queue_async */
sock_destroy /* destroy */
sock_queue_async /* queue_async */
};
@ -438,7 +443,7 @@ static int sock_signaled( struct object *obj, struct thread *thread )
struct sock *sock = (struct sock *)obj;
assert( obj->ops == &sock_ops );
return check_select_events( sock->obj.fd, sock_get_poll_events( &sock->obj ) );
return check_select_events( get_unix_fd(obj), sock_get_poll_events( &sock->obj ) );
}
static int sock_get_poll_events( struct object *obj )
@ -467,13 +472,6 @@ static int sock_get_poll_events( struct object *obj )
return ev;
}
static int sock_get_fd( struct object *obj )
{
struct sock *sock = (struct sock *)obj;
assert( obj->ops == &sock_ops );
return sock->obj.fd;
}
static int sock_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
struct sock *sock = (struct sock*) obj;
@ -592,8 +590,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne
return NULL;
}
fcntl(sockfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
if (!(sock = alloc_object( &sock_ops, -1 ))) return NULL;
sock->obj.fd = sockfd;
if (!(sock = alloc_fd_object( &sock_ops, &sock_fd_ops, -1 ))) return NULL;
set_unix_fd( &sock->obj, sockfd );
sock->state = (type != SOCK_STREAM) ? (FD_READ|FD_WRITE) : 0;
sock->mask = 0;
sock->hmask = 0;
@ -640,13 +638,13 @@ static struct sock *accept_socket( obj_handle_t handle )
* return.
*/
slen = sizeof(saddr);
acceptfd = accept(sock->obj.fd,&saddr,&slen);
acceptfd = accept( get_unix_fd(&sock->obj), &saddr, &slen);
if (acceptfd==-1) {
sock_set_error();
release_object( sock );
return NULL;
}
if (!(acceptsock = alloc_object( &sock_ops, -1 )))
if (!(acceptsock = alloc_fd_object( &sock_ops, &sock_fd_ops, acceptfd )))
{
release_object( sock );
return NULL;
@ -654,7 +652,6 @@ static struct sock *accept_socket( obj_handle_t handle )
/* newly created socket gets the same properties of the listening socket */
fcntl(acceptfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
acceptsock->obj.fd = acceptfd;
acceptsock->state = FD_WINE_CONNECTED|FD_READ|FD_WRITE;
if (sock->state & FD_WINE_NONBLOCKING)
acceptsock->state |= FD_WINE_NONBLOCKING;

View File

@ -35,6 +35,7 @@
#include "winbase.h"
#include "file.h"
#include "handle.h"
#include "process.h"
#include "thread.h"
@ -86,13 +87,18 @@ static const struct object_ops thread_ops =
remove_queue, /* remove_queue */
thread_signaled, /* signaled */
no_satisfied, /* satisfied */
no_get_fd, /* get_fd */
no_get_file_info, /* get_file_info */
destroy_thread /* destroy */
};
static const struct fd_ops thread_fd_ops =
{
NULL, /* get_poll_events */
thread_poll_event, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
destroy_thread /* destroy */
no_queue_async /* queue_async */
};
static struct thread *first_thread;
@ -144,7 +150,7 @@ struct thread *create_thread( int fd, struct process *process )
{
struct thread *thread;
if (!(thread = alloc_object( &thread_ops, fd ))) return NULL;
if (!(thread = alloc_fd_object( &thread_ops, &thread_fd_ops, fd ))) return NULL;
init_thread_structure( thread );

View File

@ -57,12 +57,8 @@ static const struct object_ops timer_ops =
remove_queue, /* remove_queue */
timer_signaled, /* signaled */
timer_satisfied, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
timer_destroy /* destroy */
};