Convert the key notifications list to a standard list.
This commit is contained in:
parent
0e0f62f2fa
commit
68abbc86e6
|
@ -52,12 +52,11 @@
|
||||||
|
|
||||||
struct notify
|
struct notify
|
||||||
{
|
{
|
||||||
|
struct list entry; /* entry in list of notifications */
|
||||||
struct event *event; /* event to set when changing this key */
|
struct event *event; /* event to set when changing this key */
|
||||||
int subtree; /* true if subtree notification */
|
int subtree; /* true if subtree notification */
|
||||||
unsigned int filter; /* which events to notify on */
|
unsigned int filter; /* which events to notify on */
|
||||||
obj_handle_t hkey; /* hkey associated with this notification */
|
obj_handle_t hkey; /* hkey associated with this notification */
|
||||||
struct notify *next; /* list of notifications */
|
|
||||||
struct notify *prev; /* list of notifications */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* a registry key */
|
/* a registry key */
|
||||||
|
@ -76,8 +75,7 @@ struct key
|
||||||
short flags; /* flags */
|
short flags; /* flags */
|
||||||
short level; /* saving level */
|
short level; /* saving level */
|
||||||
time_t modif; /* last modification time */
|
time_t modif; /* last modification time */
|
||||||
struct notify *first_notify; /* list of notifications */
|
struct list notify_list; /* list of notifications */
|
||||||
struct notify *last_notify; /* list of notifications */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* key flags */
|
/* key flags */
|
||||||
|
@ -280,28 +278,22 @@ static void do_notification( struct key *key, struct notify *notify, int del )
|
||||||
release_object( notify->event );
|
release_object( notify->event );
|
||||||
notify->event = NULL;
|
notify->event = NULL;
|
||||||
}
|
}
|
||||||
|
if (del)
|
||||||
if ( !del )
|
{
|
||||||
return;
|
list_remove( ¬ify->entry );
|
||||||
if( notify->next )
|
free( notify );
|
||||||
notify->next->prev = notify->prev;
|
}
|
||||||
else
|
|
||||||
key->last_notify = notify->prev;
|
|
||||||
if( notify->prev )
|
|
||||||
notify->prev->next = notify->next;
|
|
||||||
else
|
|
||||||
key->first_notify = notify->next;
|
|
||||||
free( notify );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct notify *find_notify( struct key *key, obj_handle_t hkey)
|
static struct notify *find_notify( struct key *key, obj_handle_t hkey)
|
||||||
{
|
{
|
||||||
struct notify *n;
|
struct notify *notify;
|
||||||
|
|
||||||
for( n=key->first_notify; n; n = n->next)
|
LIST_FOR_EACH_ENTRY( notify, &key->notify_list, struct notify, entry )
|
||||||
if( n->hkey == hkey )
|
{
|
||||||
break;
|
if (notify->hkey == hkey) return notify;
|
||||||
return n;
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close the notification associated with a handle */
|
/* close the notification associated with a handle */
|
||||||
|
@ -321,6 +313,7 @@ void registry_close_handle( struct object *obj, obj_handle_t hkey )
|
||||||
static void key_destroy( struct object *obj )
|
static void key_destroy( struct object *obj )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
struct list *ptr;
|
||||||
struct key *key = (struct key *)obj;
|
struct key *key = (struct key *)obj;
|
||||||
assert( obj->ops == &key_ops );
|
assert( obj->ops == &key_ops );
|
||||||
|
|
||||||
|
@ -337,8 +330,11 @@ static void key_destroy( struct object *obj )
|
||||||
release_object( key->subkeys[i] );
|
release_object( key->subkeys[i] );
|
||||||
}
|
}
|
||||||
/* unconditionally notify everything waiting on this key */
|
/* unconditionally notify everything waiting on this key */
|
||||||
while ( key->first_notify )
|
while ((ptr = list_head( &key->notify_list )))
|
||||||
do_notification( key, key->first_notify, 1 );
|
{
|
||||||
|
struct notify *notify = LIST_ENTRY( ptr, struct notify, entry );
|
||||||
|
do_notification( key, notify, 1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* duplicate a key path */
|
/* duplicate a key path */
|
||||||
|
@ -426,8 +422,7 @@ static struct key *alloc_key( const WCHAR *name, time_t modif )
|
||||||
key->level = current_level;
|
key->level = current_level;
|
||||||
key->modif = modif;
|
key->modif = modif;
|
||||||
key->parent = NULL;
|
key->parent = NULL;
|
||||||
key->first_notify = NULL;
|
list_init( &key->notify_list );
|
||||||
key->last_notify = NULL;
|
|
||||||
if (!(key->name = strdupW( name )))
|
if (!(key->name = strdupW( name )))
|
||||||
{
|
{
|
||||||
release_object( key );
|
release_object( key );
|
||||||
|
@ -462,13 +457,13 @@ static void make_clean( struct key *key )
|
||||||
/* go through all the notifications and send them if necessary */
|
/* go through all the notifications and send them if necessary */
|
||||||
void check_notify( struct key *key, unsigned int change, int not_subtree )
|
void check_notify( struct key *key, unsigned int change, int not_subtree )
|
||||||
{
|
{
|
||||||
struct notify *n = key->first_notify;
|
struct list *ptr, *next;
|
||||||
while (n)
|
|
||||||
|
LIST_FOR_EACH_SAFE( ptr, next, &key->notify_list )
|
||||||
{
|
{
|
||||||
struct notify *next = n->next;
|
struct notify *n = LIST_ENTRY( ptr, struct notify, entry );
|
||||||
if ( ( not_subtree || n->subtree ) && ( change & n->filter ) )
|
if ( ( not_subtree || n->subtree ) && ( change & n->filter ) )
|
||||||
do_notification( key, n, 0 );
|
do_notification( key, n, 0 );
|
||||||
n = next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1931,7 +1926,7 @@ DECL_HANDLER(set_registry_notification)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
notify = (struct notify *) malloc (sizeof(*notify));
|
notify = mem_alloc( sizeof(*notify) );
|
||||||
if( notify )
|
if( notify )
|
||||||
{
|
{
|
||||||
grab_object( event );
|
grab_object( event );
|
||||||
|
@ -1939,18 +1934,8 @@ DECL_HANDLER(set_registry_notification)
|
||||||
notify->subtree = req->subtree;
|
notify->subtree = req->subtree;
|
||||||
notify->filter = req->filter;
|
notify->filter = req->filter;
|
||||||
notify->hkey = req->hkey;
|
notify->hkey = req->hkey;
|
||||||
|
list_add_head( &key->notify_list, ¬ify->entry );
|
||||||
/* add to linked list */
|
|
||||||
notify->prev = NULL;
|
|
||||||
notify->next = key->first_notify;
|
|
||||||
if ( notify->next )
|
|
||||||
notify->next->prev = notify;
|
|
||||||
else
|
|
||||||
key->last_notify = notify;
|
|
||||||
key->first_notify = notify;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
set_error( STATUS_NO_MEMORY );
|
|
||||||
}
|
}
|
||||||
release_object( event );
|
release_object( event );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue