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 @@ ...@@ -38,6 +38,7 @@
#include "handle.h" #include "handle.h"
#include "request.h" #include "request.h"
#include "process.h" #include "process.h"
#include "esync.h"
/* IRP object */ /* IRP object */
...@@ -93,10 +94,12 @@ struct device_manager ...@@ -93,10 +94,12 @@ struct device_manager
struct list requests; /* list of pending irps across all devices */ struct list requests; /* list of pending irps across all devices */
struct irp_call *current_call; /* call currently executed on client side */ 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 */ 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 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_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 void device_manager_destroy( struct object *obj );
static const struct object_ops device_manager_ops = static const struct object_ops device_manager_ops =
...@@ -107,7 +110,7 @@ static const struct object_ops device_manager_ops = ...@@ -107,7 +110,7 @@ static const struct object_ops device_manager_ops =
add_queue, /* add_queue */ add_queue, /* add_queue */
remove_queue, /* remove_queue */ remove_queue, /* remove_queue */
device_manager_signaled, /* signaled */ device_manager_signaled, /* signaled */
NULL, /* get_esync_fd */ device_manager_get_esync_fd, /* get_esync_fd */
no_satisfied, /* satisfied */ no_satisfied, /* satisfied */
no_signal, /* signal */ no_signal, /* signal */
no_get_fd, /* get_fd */ no_get_fd, /* get_fd */
...@@ -751,6 +754,9 @@ static void delete_file( struct device_file *file ) ...@@ -751,6 +754,9 @@ static void delete_file( struct device_file *file )
/* terminate all pending requests */ /* terminate all pending requests */
LIST_FOR_EACH_ENTRY_SAFE( irp, next, &file->requests, struct irp_call, dev_entry ) 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 ); list_remove( &irp->mgr_entry );
set_irp_result( irp, STATUS_FILE_DELETED, NULL, 0, 0 ); 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 ...@@ -786,6 +792,13 @@ static int device_manager_signaled( struct object *obj, struct wait_queue_entry
return !list_empty( &manager->requests ); 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 ) static void device_manager_destroy( struct object *obj )
{ {
struct device_manager *manager = (struct device_manager *)obj; struct device_manager *manager = (struct device_manager *)obj;
...@@ -820,6 +833,9 @@ static void device_manager_destroy( struct object *obj ) ...@@ -820,6 +833,9 @@ static void device_manager_destroy( struct object *obj )
assert( !irp->file && !irp->async ); assert( !irp->file && !irp->async );
release_object( irp ); release_object( irp );
} }
if (do_esync())
close( manager->esync_fd );
} }
static struct device_manager *create_device_manager(void) static struct device_manager *create_device_manager(void)
...@@ -832,6 +848,9 @@ 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->devices );
list_init( &manager->requests ); list_init( &manager->requests );
wine_rb_init( &manager->kernel_objects, compare_kernel_object ); wine_rb_init( &manager->kernel_objects, compare_kernel_object );
if (do_esync())
manager->esync_fd = esync_create_fd( 0, 0 );
} }
return manager; return manager;
} }
...@@ -1021,6 +1040,9 @@ DECL_HANDLER(get_next_device_request) ...@@ -1021,6 +1040,9 @@ DECL_HANDLER(get_next_device_request)
/* we already own the object if it's only on manager queue */ /* we already own the object if it's only on manager queue */
if (irp->file) grab_object( irp ); if (irp->file) grab_object( irp );
manager->current_call = irp; manager->current_call = irp;
if (do_esync() && list_empty( &manager->requests ))
esync_clear( manager->esync_fd );
} }
else close_handle( current->process, reply->next ); 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