Commit bdbdf5dd authored by Zebediah Figura's avatar Zebediah Figura Committed by Vitaly Lipatov

server: Create eventfd descriptors for device manager objects.

We don't have to worry about synchronization here because wine_ntoskrnl_main_loop() is only ever called from one thread per winedevice process. This lets drivers like mountmgr finally work, and so winecfg can open the Drives tab.
parent 6267c4b8
......@@ -38,6 +38,7 @@
#include "handle.h"
#include "request.h"
#include "process.h"
#include "esync.h"
/* IRP object */
......@@ -93,10 +94,12 @@ struct device_manager
struct list requests; /* list of pending irps across all devices */
struct irp_call *current_call; /* call currently executed on client side */
struct wine_rb_tree kernel_objects; /* map of objects that have client side pointer associated */
int esync_fd; /* esync file descriptor */
};
static void device_manager_dump( struct object *obj, int verbose );
static int device_manager_signaled( struct object *obj, struct wait_queue_entry *entry );
static int device_manager_get_esync_fd( struct object *obj, enum esync_type *type );
static void device_manager_destroy( struct object *obj );
static const struct object_ops device_manager_ops =
......@@ -107,7 +110,7 @@ static const struct object_ops device_manager_ops =
add_queue, /* add_queue */
remove_queue, /* remove_queue */
device_manager_signaled, /* signaled */
NULL, /* get_esync_fd */
device_manager_get_esync_fd, /* get_esync_fd */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
......@@ -751,6 +754,9 @@ static void delete_file( struct device_file *file )
/* terminate all pending requests */
LIST_FOR_EACH_ENTRY_SAFE( irp, next, &file->requests, struct irp_call, dev_entry )
{
if (do_esync() && file->device->manager && list_empty( &file->device->manager->requests ))
esync_clear( file->device->manager->esync_fd );
list_remove( &irp->mgr_entry );
set_irp_result( irp, STATUS_FILE_DELETED, NULL, 0, 0 );
}
......@@ -786,6 +792,13 @@ static int device_manager_signaled( struct object *obj, struct wait_queue_entry
return !list_empty( &manager->requests );
}
static int device_manager_get_esync_fd( struct object *obj, enum esync_type *type )
{
struct device_manager *manager = (struct device_manager *)obj;
*type = ESYNC_MANUAL_SERVER;
return manager->esync_fd;
}
static void device_manager_destroy( struct object *obj )
{
struct device_manager *manager = (struct device_manager *)obj;
......@@ -820,6 +833,9 @@ static void device_manager_destroy( struct object *obj )
assert( !irp->file && !irp->async );
release_object( irp );
}
if (do_esync())
close( manager->esync_fd );
}
static struct device_manager *create_device_manager(void)
......@@ -832,6 +848,9 @@ static struct device_manager *create_device_manager(void)
list_init( &manager->devices );
list_init( &manager->requests );
wine_rb_init( &manager->kernel_objects, compare_kernel_object );
if (do_esync())
manager->esync_fd = esync_create_fd( 0, 0 );
}
return manager;
}
......@@ -1021,6 +1040,9 @@ DECL_HANDLER(get_next_device_request)
/* we already own the object if it's only on manager queue */
if (irp->file) grab_object( irp );
manager->current_call = irp;
if (do_esync() && list_empty( &manager->requests ))
esync_clear( manager->esync_fd );
}
else close_handle( current->process, reply->next );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment