[Wine-patches] Add event to signal when should repeat get_add_device_request (eterbug #2726)
Alexander Morozov
=?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Пн Окт 27 19:45:48 MSK 2008
----------- следующая часть -----------
From 63aaa40cac8acef5ac13233367e3283737f14ea5 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 27 Oct 2008 18:00:54 +0300
Subject: [PATCH] Add event to signal when should repeat get_add_device_request (eterbug #2726).
---
programs/winedevice/device.c | 8 +++-
server/device.c | 109 ++++++++++++++++++++++++++++++++----------
server/protocol.def | 2 +
3 files changed, 93 insertions(+), 26 deletions(-)
diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c
index 54ae128..bd11da9 100644
--- a/programs/winedevice/device.c
+++ b/programs/winedevice/device.c
@@ -297,16 +297,22 @@ static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
while (!reply_size)
{
+ HANDLE event = NULL;
+
SERVER_START_REQ( get_add_device_request )
{
+ req->event = event;
wine_server_add_data( req, drvname.Buffer, drvname.Length );
wine_server_set_reply( req, pdo_info, sizeof(pdo_info) );
ret = wine_server_call( req );
+ event = reply->event;
if (STATUS_SUCCESS == ret)
reply_size = wine_server_reply_size( reply );
}
SERVER_END_REQ;
- Sleep( 100 );
+
+ if (STATUS_PENDING == ret)
+ WaitForSingleObject( event, INFINITE );
}
pdev_obj = __wine_usbhub_get_pdo( pdo_info );
diff --git a/server/device.c b/server/device.c
index eb1b593..d424db4 100644
--- a/server/device.c
+++ b/server/device.c
@@ -173,6 +173,7 @@ struct add_dev_request
};
static void add_dev_req_dump( struct object *obj, int verbose );
+static int add_dev_req_signaled( struct object *obj, struct thread *thread );
static void add_dev_req_destroy( struct object *obj );
static const struct object_ops add_dev_requests_ops =
@@ -180,9 +181,9 @@ static const struct object_ops add_dev_requests_ops =
sizeof(struct add_dev_request), /* size */
add_dev_req_dump, /* dump */
no_get_type, /* get_type */
- no_add_queue, /* add_queue */
- NULL, /* remove_queue */
- NULL, /* signaled */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ add_dev_req_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
@@ -461,6 +462,45 @@ static struct device_manager *create_device_manager(void)
}
+static struct add_dev_request *create_add_dev_req( const struct unicode_str *drvname )
+{
+ struct add_dev_request *add_dev_req = NULL;
+ void *p;
+
+ p = mem_alloc( drvname->len );
+ if (p)
+ {
+ add_dev_req = alloc_object( &add_dev_requests_ops );
+ if (add_dev_req)
+ {
+ memcpy( p, drvname->str, drvname->len );
+ add_dev_req->drvname.len = drvname->len;
+ add_dev_req->drvname.str = p;
+ add_dev_req->data = NULL;
+ add_dev_req->size = 0;
+ list_add_tail( &add_dev_requests_list, &add_dev_req->entry );
+ }
+ else
+ free( p );
+ }
+ return add_dev_req;
+}
+
+static struct add_dev_request *get_add_dev_req( const struct unicode_str *drvname )
+{
+ struct add_dev_request *add_dev_req;
+ struct unicode_str *p;
+
+ LIST_FOR_EACH_ENTRY( add_dev_req, &add_dev_requests_list, struct add_dev_request, entry )
+ {
+ p = &add_dev_req->drvname;
+ if (p->len != drvname->len) continue;
+ if (!strncmpiW( drvname->str, p->str, p->len/sizeof(WCHAR) ))
+ return add_dev_req;
+ }
+ return NULL;
+}
+
static void add_dev_req_dump( struct object *obj, int verbose )
{
struct add_dev_request *add_dev_req = (struct add_dev_request *)obj;
@@ -472,13 +512,20 @@ static void add_dev_req_dump( struct object *obj, int verbose )
fputc( '\n', stderr );
}
+static int add_dev_req_signaled( struct object *obj, struct thread *thread )
+{
+ struct add_dev_request *add_dev_req = (struct add_dev_request *)obj;
+
+ return add_dev_req->size;
+}
+
static void add_dev_req_destroy( struct object *obj )
{
struct add_dev_request *add_dev_req = (struct add_dev_request *)obj;
list_remove( &add_dev_req->entry );
- /* data and drvname.str are in the same memory block pointed to by drvname.str */
free( (void *)add_dev_req->drvname.str );
+ free( add_dev_req->data );
}
@@ -618,23 +665,28 @@ DECL_HANDLER(call_add_device)
void *p;
struct add_dev_request *add_dev_req;
data_size_t size;
+ struct unicode_str drvname;
- size = get_req_data_size();
+ drvname.str = get_req_data();
+ drvname.len = req->drvname_len;
+ size = get_req_data_size() - req->drvname_len;
p = mem_alloc( size );
if (p)
{
- add_dev_req = alloc_object( &add_dev_requests_ops );
- if (add_dev_req)
+ add_dev_req = get_add_dev_req( &drvname );
+ if (!add_dev_req)
{
- memcpy( p, get_req_data(), size );
- add_dev_req->drvname.len = req->drvname_len;
- add_dev_req->drvname.str = p;
- add_dev_req->data = (char *)p + req->drvname_len;
- add_dev_req->size = size - req->drvname_len;
- list_add_tail( &add_dev_requests_list, &add_dev_req->entry );
+ add_dev_req = create_add_dev_req( &drvname );
+ if (!add_dev_req)
+ {
+ free( p );
+ return;
+ }
}
- else
- free( p );
+ memcpy( p, (char *)get_req_data() + req->drvname_len, size );
+ add_dev_req->data = p;
+ add_dev_req->size = size;
+ wake_up( &add_dev_req->obj, 0 );
}
}
@@ -643,25 +695,32 @@ DECL_HANDLER(get_add_device_request)
{
struct unicode_str drvname;
struct add_dev_request *add_dev_req;
- int found = 0;
+
+ if (req->event)
+ close_handle( current->process, req->event );
get_req_unicode_str( &drvname );
- LIST_FOR_EACH_ENTRY( add_dev_req, &add_dev_requests_list, struct add_dev_request, entry )
- {
- struct unicode_str *p = &add_dev_req->drvname;
+ add_dev_req = get_add_dev_req( &drvname );
- if (p->len != drvname.len) continue;
- if (!strncmpiW( drvname.str, p->str, p->len/sizeof(WCHAR) ))
+ if (!add_dev_req)
+ {
+ add_dev_req = create_add_dev_req( &drvname );
+ if (!add_dev_req)
{
- found = 1;
- break;
+ reply->event = NULL;
+ return;
}
}
- if (found)
+
+ if (add_dev_req->size)
{
set_reply_data( add_dev_req->data, add_dev_req->size );
release_object( add_dev_req );
}
else
- set_reply_data( NULL, 0 );
+ {
+ reply->event = alloc_handle( current->process, add_dev_req, SYNCHRONIZE, 0 );
+ if (reply->event)
+ set_error( STATUS_PENDING );
+ }
}
diff --git a/server/protocol.def b/server/protocol.def
index 959d782..9fc5645 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3077,8 +3077,10 @@ enum message_type
/* Check if it should call AddDevice function */
@REQ(get_add_device_request)
+ obj_handle_t event; /* old event */
VARARG(drvname,unicode_str); /* driver name */
@REPLY
+ obj_handle_t event; /* event to signal when should repeat this request */
VARARG(data,bytes); /* driver specific data */
@END
--
1.5.6.5.GIT
Подробная информация о списке рассылки Wine-patches