From 248f4b29fecfdc4105ad82d276769b723dbf033d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 7 Jul 2005 11:29:23 +0000 Subject: [PATCH] Store the global atom table in the process window station. --- server/atom.c | 79 ++++++++++++++++++++++++++++++++------------- server/object.h | 1 - server/request.c | 1 - server/user.h | 3 ++ server/winstation.c | 15 +++++++++ 5 files changed, 74 insertions(+), 25 deletions(-) diff --git a/server/atom.c b/server/atom.c index b1291d3dee8..84814e29d8c 100644 --- a/server/atom.c +++ b/server/atom.c @@ -32,6 +32,8 @@ #include "object.h" #include "process.h" #include "handle.h" +#include "user.h" +#include "winuser.h" #define HASH_SIZE 37 #define MIN_HASH_SIZE 4 @@ -80,8 +82,6 @@ static const struct object_ops atom_table_ops = atom_table_destroy /* destroy */ }; -static struct atom_table *global_table; - /* create an atom table */ static struct atom_table *create_table(int entries_count) @@ -205,12 +205,6 @@ static struct atom_entry *find_atom_entry( struct atom_table *table, const WCHAR return entry; } -/* close the atom table; used on server exit */ -void close_atom_table(void) -{ - if (global_table) release_object( global_table ); -} - /* add an atom to the table */ static atom_t add_atom( struct atom_table *table, const WCHAR *str, size_t len ) { @@ -290,24 +284,54 @@ static atom_t find_atom( struct atom_table *table, const WCHAR *str, size_t len return 0; } -static struct atom_table* get_table( obj_handle_t h ) +static struct atom_table *get_global_table( int create ) { - if (h) return (struct atom_table *)get_handle_obj( current->process, h, 0, &atom_table_ops ); + struct atom_table *global_table; + struct winstation *winstation = get_process_winstation( current->process, WINSTA_ACCESSGLOBALATOMS ); - if (!global_table && !(global_table = create_table( HASH_SIZE ))) return NULL; - return (struct atom_table *)grab_object( global_table ); + if (!winstation) return NULL; + + if (!(global_table = get_winstation_atom_table( winstation ))) + { + if (create) + { + global_table = create_table( HASH_SIZE ); + if (global_table) set_winstation_atom_table( winstation, global_table ); + } + else set_error( STATUS_OBJECT_NAME_NOT_FOUND ); + } + release_object( winstation ); + return global_table; +} + +static struct atom_table *get_table( obj_handle_t h, int create ) +{ + struct atom_table *table; + + if (h) + { + table = (struct atom_table *)get_handle_obj( current->process, h, 0, &atom_table_ops ); + } + else + { + table = get_global_table( 1 ); + if (table) grab_object( table ); + } + return table; } /* add an atom in the global table; used for window properties */ atom_t add_global_atom( const WCHAR *str, size_t len ) { - if (!global_table && !(global_table = create_table( HASH_SIZE ))) return 0; + struct atom_table *global_table = get_global_table( 1 ); + if (!global_table) return 0; return add_atom( global_table, str, len ); } /* find an atom in the global table; used for window properties */ atom_t find_global_atom( const WCHAR *str, size_t len ) { + struct atom_table *global_table = get_global_table( 0 ); struct atom_entry *entry; if (!len || len > MAX_ATOM_LEN || !global_table) return 0; @@ -321,9 +345,14 @@ int grab_global_atom( atom_t atom ) { if (atom >= MIN_STR_ATOM) { - struct atom_entry *entry = get_atom_entry( global_table, atom ); - if (entry) entry->count++; - return (entry != NULL); + struct atom_table *global_table = get_global_table( 0 ); + if (global_table) + { + struct atom_entry *entry = get_atom_entry( global_table, atom ); + if (entry) entry->count++; + return (entry != NULL); + } + else return 0; } else return 1; } @@ -331,13 +360,17 @@ int grab_global_atom( atom_t atom ) /* decrement the ref count of a global atom; used for window properties */ void release_global_atom( atom_t atom ) { - if (atom >= MIN_STR_ATOM) delete_atom( global_table, atom, 1 ); + if (atom >= MIN_STR_ATOM) + { + struct atom_table *global_table = get_global_table( 0 ); + if (global_table) delete_atom( global_table, atom, 1 ); + } } /* add a global atom */ DECL_HANDLER(add_atom) { - struct atom_table *table = get_table( req->table ); + struct atom_table *table = get_table( req->table, 1 ); if (table) { reply->atom = add_atom( table, get_req_data(), get_req_data_size() / sizeof(WCHAR) ); @@ -348,7 +381,7 @@ DECL_HANDLER(add_atom) /* delete a global atom */ DECL_HANDLER(delete_atom) { - struct atom_table *table = get_table( req->table ); + struct atom_table *table = get_table( req->table, 0 ); if (table) { delete_atom( table, req->atom, 0 ); @@ -359,7 +392,7 @@ DECL_HANDLER(delete_atom) /* find a global atom */ DECL_HANDLER(find_atom) { - struct atom_table *table = get_table( req->table ); + struct atom_table *table = get_table( req->table, 0 ); if (table) { reply->atom = find_atom( table, get_req_data(), get_req_data_size() / sizeof(WCHAR) ); @@ -370,7 +403,7 @@ DECL_HANDLER(find_atom) /* get global atom name */ DECL_HANDLER(get_atom_information) { - struct atom_table *table = get_table( req->table ); + struct atom_table *table = get_table( req->table, 0 ); if (table) { struct atom_entry *entry; @@ -391,7 +424,7 @@ DECL_HANDLER(get_atom_information) /* set global atom name */ DECL_HANDLER(set_atom_information) { - struct atom_table *table = get_table( req->table ); + struct atom_table *table = get_table( req->table, 0 ); if (table) { struct atom_entry *entry; @@ -419,7 +452,7 @@ DECL_HANDLER(init_atom_table) /* set global atom name */ DECL_HANDLER(empty_atom_table) { - struct atom_table *table = get_table( req->table ); + struct atom_table *table = get_table( req->table, 1 ); if (table) { int i; diff --git a/server/object.h b/server/object.h index 6551cf8a863..c7e29edcd97 100644 --- a/server/object.h +++ b/server/object.h @@ -157,7 +157,6 @@ extern void close_signals(void); /* atom functions */ -extern void close_atom_table(void); extern atom_t add_global_atom( const WCHAR *str, size_t len ); extern atom_t find_global_atom( const WCHAR *str, size_t len ); extern int grab_global_atom( atom_t atom ); diff --git a/server/request.c b/server/request.c index 4a2c80ae0f3..8e3f79bf0bf 100644 --- a/server/request.c +++ b/server/request.c @@ -798,7 +798,6 @@ static void close_socket_timeout( void *arg ) close_global_hooks(); close_global_handles(); close_registry(); - close_atom_table(); dump_objects(); /* dump any remaining objects */ #else exit(0); diff --git a/server/user.h b/server/user.h index 2c84f06099f..44d8f389c54 100644 --- a/server/user.h +++ b/server/user.h @@ -29,6 +29,7 @@ struct window; struct msg_queue; struct hook_table; struct window_class; +struct atom_table; struct clipboard; enum user_object @@ -123,7 +124,9 @@ extern void *get_class_client_ptr( struct window_class *class ); extern struct winstation *get_process_winstation( struct process *process, unsigned int access ); extern void set_winstation_clipboard( struct winstation *winstation, struct clipboard *clipboard ); +extern void set_winstation_atom_table( struct winstation *winstation, struct atom_table *table ); extern struct clipboard *get_winstation_clipboard( struct winstation *winstation ); +extern struct atom_table *get_winstation_atom_table( struct winstation *winstation ); extern void connect_process_winstation( struct process *process, const WCHAR *name, size_t len ); extern void connect_process_desktop( struct process *process, const WCHAR *name, size_t len ); extern void close_thread_desktop( struct thread *thread ); diff --git a/server/winstation.c b/server/winstation.c index 54d95d03bb0..0d473cad506 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -42,6 +42,7 @@ struct winstation struct list entry; /* entry in global winstation list */ struct list desktops; /* list of desktops of this winstation */ struct clipboard *clipboard; /* clipboard information */ + struct atom_table *atom_table; /* global atom table */ }; struct desktop @@ -115,6 +116,7 @@ static struct winstation *create_winstation( const WCHAR *name, size_t len, unsi /* initialize it if it didn't already exist */ winstation->flags = flags; winstation->clipboard = NULL; + winstation->atom_table = NULL; list_add_tail( &winstation_list, &winstation->entry ); list_init( &winstation->desktops ); } @@ -143,6 +145,7 @@ static void winstation_destroy( struct object *obj ) if (winstation == interactive_winstation) interactive_winstation = NULL; list_remove( &winstation->entry ); if (winstation->clipboard) release_object( winstation->clipboard ); + if (winstation->atom_table) release_object( winstation->atom_table ); } /* retrieve the process window station, checking the handle access rights */ @@ -164,6 +167,18 @@ struct clipboard *get_winstation_clipboard( struct winstation *winstation ) return winstation->clipboard; } +/* set the pointer to the (opaque) atom table */ +void set_winstation_atom_table( struct winstation *winstation, struct atom_table *table ) +{ + winstation->atom_table = table; +} + +/* retrieve the pointer to the (opaque) clipboard info */ +struct atom_table *get_winstation_atom_table( struct winstation *winstation ) +{ + return winstation->atom_table; +} + /* build the full name of a desktop object */ static WCHAR *build_desktop_name( const WCHAR *name, size_t len, struct winstation *winstation, size_t *res_len )