Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/tests/reg.c | 61 ++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 17 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 9335d9cc927..a619bc45cb8 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1853,28 +1853,30 @@ static void test_notify(void) LARGE_INTEGER timeout; IO_STATUS_BLOCK iosb; UNICODE_STRING str; - HANDLE key, events[2], subkey; + HANDLE key, key2, events[4], subkey; NTSTATUS status; + unsigned int i;
InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0); status = pNtOpenKey(&key, KEY_ALL_ACCESS, &attr); ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status); + status = pNtOpenKey(&key2, KEY_ALL_ACCESS, &attr); + ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status);
- events[0] = CreateEventW(NULL, FALSE, TRUE, NULL); - ok(events[0] != NULL, "CreateEvent failed: %u\n", GetLastError()); - events[1] = CreateEventW(NULL, FALSE, TRUE, NULL); - ok(events[1] != NULL, "CreateEvent failed: %u\n", GetLastError()); + for (i = 0; i < ARRAY_SIZE(events); ++i) + events[i] = CreateEventW(NULL, TRUE, TRUE, NULL);
status = pNtNotifyChangeKey(key, events[0], NULL, NULL, &iosb, REG_NOTIFY_CHANGE_NAME, FALSE, NULL, 0, TRUE); ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %x\n", status); - status = pNtNotifyChangeKey(key, events[1], NULL, NULL, &iosb, REG_NOTIFY_CHANGE_NAME, FALSE, NULL, 0, TRUE); + status = pNtNotifyChangeKey(key, events[1], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE); + ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %x\n", status); + status = pNtNotifyChangeKey(key2, events[2], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE); + ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %x\n", status); + status = pNtNotifyChangeKey(key2, events[3], NULL, NULL, &iosb, REG_NOTIFY_CHANGE_NAME, FALSE, NULL, 0, TRUE); ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %x\n", status);
- timeout.QuadPart = 0; - status = pNtWaitForSingleObject(events[0], FALSE, &timeout); - ok(status == STATUS_TIMEOUT, "NtWaitForSingleObject returned %x\n", status); - status = pNtWaitForSingleObject(events[1], FALSE, &timeout); - ok(status == STATUS_TIMEOUT, "NtWaitForSingleObject returned %x\n", status); + status = WaitForMultipleObjects(4, events, FALSE, 0); + ok(status == WAIT_TIMEOUT, "got %d\n", status);
attr.RootDirectory = key; attr.ObjectName = &str; @@ -1885,22 +1887,43 @@ static void test_notify(void) pRtlFreeUnicodeString(&str);
status = pNtWaitForSingleObject(events[0], FALSE, &timeout); - todo_wine ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status); + todo_wine ok(!status, "got %#x\n", status); status = pNtWaitForSingleObject(events[1], FALSE, &timeout); - ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status); + ok(!status, "got %#x\n", status); + status = pNtWaitForSingleObject(events[2], FALSE, &timeout); + ok(status == STATUS_TIMEOUT, "got %#x\n", status); + status = pNtWaitForSingleObject(events[3], FALSE, &timeout); + ok(status == STATUS_TIMEOUT, "got %#x\n", status);
status = pNtNotifyChangeKey(key, events[0], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE); ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %x\n", status); + + status = pNtWaitForSingleObject(events[0], FALSE, &timeout); + ok(status == STATUS_TIMEOUT, "got %#x\n", status); + status = pNtWaitForSingleObject(events[1], FALSE, &timeout); + ok(!status, "got %#x\n", status); + status = pNtWaitForSingleObject(events[2], FALSE, &timeout); + ok(status == STATUS_TIMEOUT, "got %#x\n", status); + status = pNtWaitForSingleObject(events[3], FALSE, &timeout); + ok(status == STATUS_TIMEOUT, "got %#x\n", status); + status = pNtNotifyChangeKey(key, events[1], NULL, NULL, &iosb, 0, FALSE, NULL, 0, TRUE); ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %x\n", status);
+ status = WaitForMultipleObjects(4, events, FALSE, 0); + ok(status == WAIT_TIMEOUT, "got %d\n", status); + status = pNtDeleteKey(subkey); ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %x\n", status);
status = pNtWaitForSingleObject(events[0], FALSE, &timeout); - todo_wine ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status); + todo_wine ok(!status, "got %#x\n", status); status = pNtWaitForSingleObject(events[1], FALSE, &timeout); - ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status); + ok(!status, "got %#x\n", status); + status = pNtWaitForSingleObject(events[2], FALSE, &timeout); + ok(status == STATUS_TIMEOUT, "got %#x\n", status); + status = pNtWaitForSingleObject(events[3], FALSE, &timeout); + ok(status == STATUS_TIMEOUT, "got %#x\n", status);
pNtClose(subkey);
@@ -1912,9 +1935,13 @@ static void test_notify(void) pNtClose(key);
status = pNtWaitForSingleObject(events[0], FALSE, &timeout); - todo_wine ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status); + todo_wine ok(!status, "got %#x\n", status); status = pNtWaitForSingleObject(events[1], FALSE, &timeout); - ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status); + ok(!status, "got %#x\n", status); + status = pNtWaitForSingleObject(events[2], FALSE, &timeout); + ok(status == STATUS_TIMEOUT, "got %#x\n", status); + status = pNtWaitForSingleObject(events[3], FALSE, &timeout); + ok(status == STATUS_TIMEOUT, "got %#x\n", status);
if (pNtNotifyChangeMultipleKeys) {
From: Sebastian Lackner sebastian@fds-team.de
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- The original wine-staging patch uses a linked list here. I changed it to use a flat array instead, as the latter seemed simpler.
The original wine-staging patch is also accompanied by a subsequent patch introducing reference counting, which as far as I can tell has no effect.
I have been unable to locate any reference to an application related to this patch.
dlls/ntdll/tests/reg.c | 6 +++--- server/registry.c | 41 ++++++++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index a619bc45cb8..ac1dec9f2f8 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1887,7 +1887,7 @@ static void test_notify(void) pRtlFreeUnicodeString(&str);
status = pNtWaitForSingleObject(events[0], FALSE, &timeout); - todo_wine ok(!status, "got %#x\n", status); + ok(!status, "got %#x\n", status); status = pNtWaitForSingleObject(events[1], FALSE, &timeout); ok(!status, "got %#x\n", status); status = pNtWaitForSingleObject(events[2], FALSE, &timeout); @@ -1917,7 +1917,7 @@ static void test_notify(void) ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %x\n", status);
status = pNtWaitForSingleObject(events[0], FALSE, &timeout); - todo_wine ok(!status, "got %#x\n", status); + ok(!status, "got %#x\n", status); status = pNtWaitForSingleObject(events[1], FALSE, &timeout); ok(!status, "got %#x\n", status); status = pNtWaitForSingleObject(events[2], FALSE, &timeout); @@ -1935,7 +1935,7 @@ static void test_notify(void) pNtClose(key);
status = pNtWaitForSingleObject(events[0], FALSE, &timeout); - todo_wine ok(!status, "got %#x\n", status); + ok(!status, "got %#x\n", status); status = pNtWaitForSingleObject(events[1], FALSE, &timeout); ok(!status, "got %#x\n", status); status = pNtWaitForSingleObject(events[2], FALSE, &timeout); diff --git a/server/registry.c b/server/registry.c index c937e051597..64aec1d83c9 100644 --- a/server/registry.c +++ b/server/registry.c @@ -52,7 +52,8 @@ struct notify { struct list entry; /* entry in list of notifications */ - struct event *event; /* event to set when changing this key */ + struct event **events; /* events to set when changing this key */ + unsigned int event_count; /* number of events */ int subtree; /* true if subtree notification */ unsigned int filter; /* which events to notify on */ obj_handle_t hkey; /* hkey associated with this notification */ @@ -314,12 +315,17 @@ static struct object_type *key_get_type( struct object *obj ) /* notify waiter and maybe delete the notification */ static void do_notification( struct key *key, struct notify *notify, int del ) { - if (notify->event) + unsigned int i; + + for (i = 0; i < notify->event_count; ++i) { - set_event( notify->event ); - release_object( notify->event ); - notify->event = NULL; + set_event( notify->events[i] ); + release_object( notify->events[i] ); } + free( notify->events ); + notify->events = NULL; + notify->event_count = 0; + if (del) { list_remove( ¬ify->entry ); @@ -2283,20 +2289,13 @@ DECL_HANDLER(set_registry_notification) if (event) { notify = find_notify( key, current->process, req->hkey ); - if (notify) - { - if (notify->event) - release_object( notify->event ); - grab_object( event ); - notify->event = event; - } - else + if (!notify) { notify = mem_alloc( sizeof(*notify) ); if (notify) { - grab_object( event ); - notify->event = event; + notify->events = NULL; + notify->event_count = 0; notify->subtree = req->subtree; notify->filter = req->filter; notify->hkey = req->hkey; @@ -2306,8 +2305,16 @@ DECL_HANDLER(set_registry_notification) } if (notify) { - reset_event( event ); - set_error( STATUS_PENDING ); + struct event **new_array; + + if ((new_array = realloc( notify->events, (notify->event_count + 1) * sizeof(*notify->events) ))) + { + notify->events = new_array; + notify->events[notify->event_count++] = (struct event *)grab_object( event ); + reset_event( event ); + set_error( STATUS_PENDING ); + } + else set_error( STATUS_NO_MEMORY ); } release_object( event ); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=84593
Your paranoid android.
=== w8 (32 bit report) ===
ntdll: reg: Timeout
=== w8adm (32 bit report) ===
ntdll: reg: Timeout
=== w864 (32 bit report) ===
ntdll: reg: Timeout
=== w1064v1507 (32 bit report) ===
ntdll: reg: Timeout
=== w1064v1809 (32 bit report) ===
ntdll: reg: Timeout
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=84592
Your paranoid android.
=== w8 (testbot log) ===
The task timed out
=== w8adm (32 bit report) ===
ntdll: reg: Timeout
=== w864 (32 bit report) ===
ntdll: reg: Timeout
=== w1064v1507 (32 bit report) ===
ntdll: reg: Timeout
=== w1064v1507 (testbot log) ===
The task timed out
=== w1064v1809 (32 bit report) ===
ntdll: reg: Timeout