Commit e6267369 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- changed ATOM support in wineserver to match NTDLL needs

- adapted accordingly kernel32 atom support
parent d7272ded
...@@ -48,6 +48,31 @@ WINE_DEFAULT_DEBUG_CHANNEL(atom); ...@@ -48,6 +48,31 @@ WINE_DEFAULT_DEBUG_CHANNEL(atom);
#define MAX_ATOM_LEN 255 #define MAX_ATOM_LEN 255
static struct atom_table* get_local_table(DWORD entries)
{
static struct atom_table* local_table;
if (!local_table)
{
NTSTATUS status;
struct atom_table* table;
SERVER_START_REQ( init_atom_table )
{
req->entries = entries;
status = wine_server_call( req );
table = reply->table;
}
SERVER_END_REQ;
if (status)
SetLastError( RtlNtStatusToDosError( status ) );
else if (InterlockedCompareExchangePointer((void*)&local_table, table, NULL) != NULL)
NtClose((HANDLE)table);
}
return local_table;
}
/*********************************************************************** /***********************************************************************
* ATOM_IsIntAtomA * ATOM_IsIntAtomA
*/ */
...@@ -116,18 +141,11 @@ static BOOL ATOM_IsIntAtomW(LPCWSTR atomstr,WORD *atomid) ...@@ -116,18 +141,11 @@ static BOOL ATOM_IsIntAtomW(LPCWSTR atomstr,WORD *atomid)
*/ */
BOOL WINAPI InitAtomTable( DWORD entries ) BOOL WINAPI InitAtomTable( DWORD entries )
{ {
BOOL ret; return get_local_table( entries ) ? TRUE : FALSE;
SERVER_START_REQ( init_atom_table )
{
req->entries = entries;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
} }
static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local ) static ATOM ATOM_AddAtomA( LPCSTR str, struct atom_table* table )
{ {
ATOM atom = 0; ATOM atom = 0;
if (!ATOM_IsIntAtomA( str, &atom )) if (!ATOM_IsIntAtomA( str, &atom ))
...@@ -143,12 +161,12 @@ static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local ) ...@@ -143,12 +161,12 @@ static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local )
SERVER_START_REQ( add_atom ) SERVER_START_REQ( add_atom )
{ {
wine_server_add_data( req, buffer, len * sizeof(WCHAR) ); wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
req->local = local; req->table = table;
if (!wine_server_call_err(req)) atom = reply->atom; if (!wine_server_call_err(req)) atom = reply->atom;
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_a(str), atom ); TRACE( "(%s) %s -> %x\n", table ? "local" : "global", debugstr_a(str), atom );
return atom; return atom;
} }
...@@ -165,7 +183,7 @@ static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local ) ...@@ -165,7 +183,7 @@ static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local )
*/ */
ATOM WINAPI GlobalAddAtomA( LPCSTR str /* [in] String to add */ ) ATOM WINAPI GlobalAddAtomA( LPCSTR str /* [in] String to add */ )
{ {
return ATOM_AddAtomA( str, FALSE ); return ATOM_AddAtomA( str, NULL );
} }
...@@ -181,11 +199,11 @@ ATOM WINAPI GlobalAddAtomA( LPCSTR str /* [in] String to add */ ) ...@@ -181,11 +199,11 @@ ATOM WINAPI GlobalAddAtomA( LPCSTR str /* [in] String to add */ )
*/ */
ATOM WINAPI AddAtomA( LPCSTR str /* [in] String to add */ ) ATOM WINAPI AddAtomA( LPCSTR str /* [in] String to add */ )
{ {
return ATOM_AddAtomA( str, TRUE ); return ATOM_AddAtomA( str, get_local_table(0) );
} }
static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local ) static ATOM ATOM_AddAtomW( LPCWSTR str, struct atom_table* table )
{ {
ATOM atom = 0; ATOM atom = 0;
if (!ATOM_IsIntAtomW( str, &atom )) if (!ATOM_IsIntAtomW( str, &atom ))
...@@ -198,13 +216,13 @@ static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local ) ...@@ -198,13 +216,13 @@ static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local )
} }
SERVER_START_REQ( add_atom ) SERVER_START_REQ( add_atom )
{ {
req->local = local; req->table = table;
wine_server_add_data( req, str, len * sizeof(WCHAR) ); wine_server_add_data( req, str, len * sizeof(WCHAR) );
if (!wine_server_call_err(req)) atom = reply->atom; if (!wine_server_call_err(req)) atom = reply->atom;
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_w(str), atom ); TRACE( "(%s) %s -> %x\n", table ? "local" : "global", debugstr_w(str), atom );
return atom; return atom;
} }
...@@ -216,7 +234,7 @@ static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local ) ...@@ -216,7 +234,7 @@ static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local )
*/ */
ATOM WINAPI GlobalAddAtomW( LPCWSTR str ) ATOM WINAPI GlobalAddAtomW( LPCWSTR str )
{ {
return ATOM_AddAtomW( str, FALSE ); return ATOM_AddAtomW( str, NULL );
} }
...@@ -227,19 +245,19 @@ ATOM WINAPI GlobalAddAtomW( LPCWSTR str ) ...@@ -227,19 +245,19 @@ ATOM WINAPI GlobalAddAtomW( LPCWSTR str )
*/ */
ATOM WINAPI AddAtomW( LPCWSTR str ) ATOM WINAPI AddAtomW( LPCWSTR str )
{ {
return ATOM_AddAtomW( str, TRUE ); return ATOM_AddAtomW( str, get_local_table(0) );
} }
static ATOM ATOM_DeleteAtom( ATOM atom, BOOL local) static ATOM ATOM_DeleteAtom( ATOM atom, struct atom_table* table )
{ {
TRACE( "(%s) %x\n", local ? "local" : "global", atom ); TRACE( "(%s) %x\n", table ? "local" : "global", atom );
if (atom >= MAXINTATOM) if (atom >= MAXINTATOM)
{ {
SERVER_START_REQ( delete_atom ) SERVER_START_REQ( delete_atom )
{ {
req->atom = atom; req->atom = atom;
req->local = local; req->table = table;
wine_server_call_err( req ); wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -260,7 +278,7 @@ static ATOM ATOM_DeleteAtom( ATOM atom, BOOL local) ...@@ -260,7 +278,7 @@ static ATOM ATOM_DeleteAtom( ATOM atom, BOOL local)
*/ */
ATOM WINAPI GlobalDeleteAtom( ATOM atom /* [in] Atom to delete */ ) ATOM WINAPI GlobalDeleteAtom( ATOM atom /* [in] Atom to delete */ )
{ {
return ATOM_DeleteAtom( atom, FALSE); return ATOM_DeleteAtom( atom, NULL);
} }
...@@ -276,11 +294,11 @@ ATOM WINAPI GlobalDeleteAtom( ATOM atom /* [in] Atom to delete */ ) ...@@ -276,11 +294,11 @@ ATOM WINAPI GlobalDeleteAtom( ATOM atom /* [in] Atom to delete */ )
*/ */
ATOM WINAPI DeleteAtom( ATOM atom /* [in] Atom to delete */ ) ATOM WINAPI DeleteAtom( ATOM atom /* [in] Atom to delete */ )
{ {
return ATOM_DeleteAtom( atom, TRUE ); return ATOM_DeleteAtom( atom, get_local_table(0) );
} }
static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local ) static ATOM ATOM_FindAtomA( LPCSTR str, struct atom_table* table )
{ {
ATOM atom = 0; ATOM atom = 0;
if (!ATOM_IsIntAtomA( str, &atom )) if (!ATOM_IsIntAtomA( str, &atom ))
...@@ -295,13 +313,13 @@ static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local ) ...@@ -295,13 +313,13 @@ static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local )
} }
SERVER_START_REQ( find_atom ) SERVER_START_REQ( find_atom )
{ {
req->local = local; req->table = table;
wine_server_add_data( req, buffer, len * sizeof(WCHAR) ); wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
if (!wine_server_call_err(req)) atom = reply->atom; if (!wine_server_call_err(req)) atom = reply->atom;
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_a(str), atom ); TRACE( "(%s) %s -> %x\n", table ? "local" : "global", debugstr_a(str), atom );
return atom; return atom;
} }
...@@ -317,7 +335,7 @@ static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local ) ...@@ -317,7 +335,7 @@ static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local )
*/ */
ATOM WINAPI GlobalFindAtomA( LPCSTR str /* [in] Pointer to string to search for */ ) ATOM WINAPI GlobalFindAtomA( LPCSTR str /* [in] Pointer to string to search for */ )
{ {
return ATOM_FindAtomA( str, FALSE ); return ATOM_FindAtomA( str, NULL );
} }
/*********************************************************************** /***********************************************************************
...@@ -331,11 +349,11 @@ ATOM WINAPI GlobalFindAtomA( LPCSTR str /* [in] Pointer to string to search for ...@@ -331,11 +349,11 @@ ATOM WINAPI GlobalFindAtomA( LPCSTR str /* [in] Pointer to string to search for
*/ */
ATOM WINAPI FindAtomA( LPCSTR str /* [in] Pointer to string to find */ ) ATOM WINAPI FindAtomA( LPCSTR str /* [in] Pointer to string to find */ )
{ {
return ATOM_FindAtomA( str, TRUE ); return ATOM_FindAtomA( str, get_local_table(0) );
} }
static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local ) static ATOM ATOM_FindAtomW( LPCWSTR str, struct atom_table* table )
{ {
ATOM atom = 0; ATOM atom = 0;
if (!ATOM_IsIntAtomW( str, &atom )) if (!ATOM_IsIntAtomW( str, &atom ))
...@@ -349,12 +367,12 @@ static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local ) ...@@ -349,12 +367,12 @@ static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local )
SERVER_START_REQ( find_atom ) SERVER_START_REQ( find_atom )
{ {
wine_server_add_data( req, str, len * sizeof(WCHAR) ); wine_server_add_data( req, str, len * sizeof(WCHAR) );
req->local = local; req->table = table;
if (!wine_server_call_err( req )) atom = reply->atom; if (!wine_server_call_err( req )) atom = reply->atom;
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_w(str), atom ); TRACE( "(%s) %s -> %x\n", table ? "local" : "global", debugstr_w(str), atom );
return atom; return atom;
} }
...@@ -366,7 +384,7 @@ static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local ) ...@@ -366,7 +384,7 @@ static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local )
*/ */
ATOM WINAPI GlobalFindAtomW( LPCWSTR str ) ATOM WINAPI GlobalFindAtomW( LPCWSTR str )
{ {
return ATOM_FindAtomW( str, FALSE ); return ATOM_FindAtomW( str, NULL );
} }
...@@ -377,11 +395,11 @@ ATOM WINAPI GlobalFindAtomW( LPCWSTR str ) ...@@ -377,11 +395,11 @@ ATOM WINAPI GlobalFindAtomW( LPCWSTR str )
*/ */
ATOM WINAPI FindAtomW( LPCWSTR str ) ATOM WINAPI FindAtomW( LPCWSTR str )
{ {
return ATOM_FindAtomW( str, TRUE ); return ATOM_FindAtomW( str, get_local_table(0) );
} }
static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local ) static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, struct atom_table* table )
{ {
INT len; INT len;
...@@ -406,10 +424,10 @@ static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local ) ...@@ -406,10 +424,10 @@ static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local )
WCHAR full_name[MAX_ATOM_LEN]; WCHAR full_name[MAX_ATOM_LEN];
len = 0; len = 0;
SERVER_START_REQ( get_atom_name ) SERVER_START_REQ( get_atom_information )
{ {
req->atom = atom; req->atom = atom;
req->local = local; req->table = table;
wine_server_set_reply( req, full_name, sizeof(full_name) ); wine_server_set_reply( req, full_name, sizeof(full_name) );
if (!wine_server_call_err( req )) if (!wine_server_call_err( req ))
{ {
...@@ -429,7 +447,7 @@ static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local ) ...@@ -429,7 +447,7 @@ static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local )
buffer[count-1] = 0; buffer[count-1] = 0;
return 0; return 0;
} }
TRACE( "(%s) %x -> %s\n", local ? "local" : "global", atom, debugstr_a(buffer) ); TRACE( "(%s) %x -> %s\n", table ? "local" : "global", atom, debugstr_a(buffer) );
return len; return len;
} }
...@@ -448,7 +466,7 @@ UINT WINAPI GlobalGetAtomNameA( ...@@ -448,7 +466,7 @@ UINT WINAPI GlobalGetAtomNameA(
LPSTR buffer, /* [out] Pointer to buffer for atom string */ LPSTR buffer, /* [out] Pointer to buffer for atom string */
INT count ) /* [in] Size of buffer */ INT count ) /* [in] Size of buffer */
{ {
return ATOM_GetAtomNameA( atom, buffer, count, FALSE ); return ATOM_GetAtomNameA( atom, buffer, count, NULL );
} }
...@@ -466,11 +484,11 @@ UINT WINAPI GetAtomNameA( ...@@ -466,11 +484,11 @@ UINT WINAPI GetAtomNameA(
LPSTR buffer, /* [out] Pointer to string for atom string */ LPSTR buffer, /* [out] Pointer to string for atom string */
INT count) /* [in] Size of buffer */ INT count) /* [in] Size of buffer */
{ {
return ATOM_GetAtomNameA( atom, buffer, count, TRUE ); return ATOM_GetAtomNameA( atom, buffer, count, get_local_table(0) );
} }
static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local ) static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, struct atom_table* table )
{ {
INT len; INT len;
...@@ -496,10 +514,10 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local ) ...@@ -496,10 +514,10 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local )
WCHAR full_name[MAX_ATOM_LEN]; WCHAR full_name[MAX_ATOM_LEN];
len = 0; len = 0;
SERVER_START_REQ( get_atom_name ) SERVER_START_REQ( get_atom_information )
{ {
req->atom = atom; req->atom = atom;
req->local = local; req->table = table;
wine_server_set_reply( req, full_name, sizeof(full_name) ); wine_server_set_reply( req, full_name, sizeof(full_name) );
if (!wine_server_call_err( req )) if (!wine_server_call_err( req ))
{ {
...@@ -512,7 +530,7 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local ) ...@@ -512,7 +530,7 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local )
SERVER_END_REQ; SERVER_END_REQ;
if (!len) return 0; if (!len) return 0;
} }
TRACE( "(%s) %x -> %s\n", local ? "local" : "global", atom, debugstr_w(buffer) ); TRACE( "(%s) %x -> %s\n", table ? "local" : "global", atom, debugstr_w(buffer) );
return len; return len;
} }
...@@ -524,7 +542,7 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local ) ...@@ -524,7 +542,7 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local )
*/ */
UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count ) UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
{ {
return ATOM_GetAtomNameW( atom, buffer, count, FALSE); return ATOM_GetAtomNameW( atom, buffer, count, NULL);
} }
...@@ -535,5 +553,5 @@ UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count ) ...@@ -535,5 +553,5 @@ UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
*/ */
UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count ) UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
{ {
return ATOM_GetAtomNameW( atom, buffer, count, TRUE ); return ATOM_GetAtomNameW( atom, buffer, count, get_local_table(0) );
} }
...@@ -1990,7 +1990,7 @@ struct get_selector_entry_reply ...@@ -1990,7 +1990,7 @@ struct get_selector_entry_reply
struct add_atom_request struct add_atom_request
{ {
struct request_header __header; struct request_header __header;
int local; obj_handle_t table;
/* VARARG(name,unicode_str); */ /* VARARG(name,unicode_str); */
}; };
struct add_atom_reply struct add_atom_reply
...@@ -2004,8 +2004,8 @@ struct add_atom_reply ...@@ -2004,8 +2004,8 @@ struct add_atom_reply
struct delete_atom_request struct delete_atom_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t table;
atom_t atom; atom_t atom;
int local;
}; };
struct delete_atom_reply struct delete_atom_reply
{ {
...@@ -2017,7 +2017,7 @@ struct delete_atom_reply ...@@ -2017,7 +2017,7 @@ struct delete_atom_reply
struct find_atom_request struct find_atom_request
{ {
struct request_header __header; struct request_header __header;
int local; obj_handle_t table;
/* VARARG(name,unicode_str); */ /* VARARG(name,unicode_str); */
}; };
struct find_atom_reply struct find_atom_reply
...@@ -2028,21 +2028,49 @@ struct find_atom_reply ...@@ -2028,21 +2028,49 @@ struct find_atom_reply
struct get_atom_name_request struct get_atom_information_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t table;
atom_t atom; atom_t atom;
int local;
}; };
struct get_atom_name_reply struct get_atom_information_reply
{ {
struct reply_header __header; struct reply_header __header;
int count; int count;
int pinned;
/* VARARG(name,unicode_str); */ /* VARARG(name,unicode_str); */
}; };
struct set_atom_information_request
{
struct request_header __header;
obj_handle_t table;
atom_t atom;
int pinned;
};
struct set_atom_information_reply
{
struct reply_header __header;
};
struct empty_atom_table_request
{
struct request_header __header;
obj_handle_t table;
int if_pinned;
};
struct empty_atom_table_reply
{
struct reply_header __header;
};
struct init_atom_table_request struct init_atom_table_request
{ {
struct request_header __header; struct request_header __header;
...@@ -2051,6 +2079,7 @@ struct init_atom_table_request ...@@ -2051,6 +2079,7 @@ struct init_atom_table_request
struct init_atom_table_reply struct init_atom_table_reply
{ {
struct reply_header __header; struct reply_header __header;
obj_handle_t table;
}; };
...@@ -3448,7 +3477,9 @@ enum request ...@@ -3448,7 +3477,9 @@ enum request
REQ_add_atom, REQ_add_atom,
REQ_delete_atom, REQ_delete_atom,
REQ_find_atom, REQ_find_atom,
REQ_get_atom_name, REQ_get_atom_information,
REQ_set_atom_information,
REQ_empty_atom_table,
REQ_init_atom_table, REQ_init_atom_table,
REQ_get_msg_queue, REQ_get_msg_queue,
REQ_set_queue_mask, REQ_set_queue_mask,
...@@ -3645,7 +3676,9 @@ union generic_request ...@@ -3645,7 +3676,9 @@ union generic_request
struct add_atom_request add_atom_request; struct add_atom_request add_atom_request;
struct delete_atom_request delete_atom_request; struct delete_atom_request delete_atom_request;
struct find_atom_request find_atom_request; struct find_atom_request find_atom_request;
struct get_atom_name_request get_atom_name_request; struct get_atom_information_request get_atom_information_request;
struct set_atom_information_request set_atom_information_request;
struct empty_atom_table_request empty_atom_table_request;
struct init_atom_table_request init_atom_table_request; struct init_atom_table_request init_atom_table_request;
struct get_msg_queue_request get_msg_queue_request; struct get_msg_queue_request get_msg_queue_request;
struct set_queue_mask_request set_queue_mask_request; struct set_queue_mask_request set_queue_mask_request;
...@@ -3840,7 +3873,9 @@ union generic_reply ...@@ -3840,7 +3873,9 @@ union generic_reply
struct add_atom_reply add_atom_reply; struct add_atom_reply add_atom_reply;
struct delete_atom_reply delete_atom_reply; struct delete_atom_reply delete_atom_reply;
struct find_atom_reply find_atom_reply; struct find_atom_reply find_atom_reply;
struct get_atom_name_reply get_atom_name_reply; struct get_atom_information_reply get_atom_information_reply;
struct set_atom_information_reply set_atom_information_reply;
struct empty_atom_table_reply empty_atom_table_reply;
struct init_atom_table_reply init_atom_table_reply; struct init_atom_table_reply init_atom_table_reply;
struct get_msg_queue_reply get_msg_queue_reply; struct get_msg_queue_reply get_msg_queue_reply;
struct set_queue_mask_reply set_queue_mask_reply; struct set_queue_mask_reply set_queue_mask_reply;
...@@ -3919,6 +3954,6 @@ union generic_reply ...@@ -3919,6 +3954,6 @@ union generic_reply
struct set_mailslot_info_reply set_mailslot_info_reply; struct set_mailslot_info_reply set_mailslot_info_reply;
}; };
#define SERVER_PROTOCOL_VERSION 172 #define SERVER_PROTOCOL_VERSION 173
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "request.h" #include "request.h"
#include "object.h" #include "object.h"
#include "process.h" #include "process.h"
#include "handle.h"
#define HASH_SIZE 37 #define HASH_SIZE 37
#define MIN_HASH_SIZE 4 #define MIN_HASH_SIZE 4
...@@ -45,6 +46,7 @@ struct atom_entry ...@@ -45,6 +46,7 @@ struct atom_entry
struct atom_entry *next; /* hash table list */ struct atom_entry *next; /* hash table list */
struct atom_entry *prev; /* hash table list */ struct atom_entry *prev; /* hash table list */
int count; /* reference count */ int count; /* reference count */
int pinned; /* whether the atom is pinned or not */
int hash; /* string hash */ int hash; /* string hash */
atom_t atom; /* atom handle */ atom_t atom; /* atom handle */
WCHAR str[1]; /* atom string */ WCHAR str[1]; /* atom string */
...@@ -185,8 +187,9 @@ static void atom_table_dump( struct object *obj, int verbose ) ...@@ -185,8 +187,9 @@ static void atom_table_dump( struct object *obj, int verbose )
{ {
struct atom_entry *entry = table->handles[i]; struct atom_entry *entry = table->handles[i];
if (!entry) continue; if (!entry) continue;
fprintf( stderr, " %04x: ref=%d hash=%d \"", entry->atom, entry->count, entry->hash ); fprintf( stderr, " %04x: ref=%d pinned=%c hash=%d \"",
dump_strW( entry->str, strlenW(entry->str), stderr, "\"\""); entry->atom, entry->count, entry->pinned ? 'Y' : 'N', entry->hash );
dump_strW( entry->str, strlenW( entry->str ), stderr, "\"\"");
fprintf( stderr, "\"\n" ); fprintf( stderr, "\"\n" );
} }
} }
...@@ -249,6 +252,7 @@ static atom_t add_atom( struct atom_table *table, const WCHAR *str ) ...@@ -249,6 +252,7 @@ static atom_t add_atom( struct atom_table *table, const WCHAR *str )
if ((entry->next = table->entries[hash])) entry->next->prev = entry; if ((entry->next = table->entries[hash])) entry->next->prev = entry;
table->entries[hash] = entry; table->entries[hash] = entry;
entry->count = 1; entry->count = 1;
entry->pinned = 0;
entry->hash = hash; entry->hash = hash;
strcpyW( entry->str, str ); strcpyW( entry->str, str );
} }
...@@ -302,53 +306,128 @@ void release_global_atom( atom_t atom ) ...@@ -302,53 +306,128 @@ void release_global_atom( atom_t atom )
if (atom >= MIN_STR_ATOM) delete_atom( global_table, atom ); if (atom >= MIN_STR_ATOM) delete_atom( global_table, atom );
} }
static struct atom_table* get_table( obj_handle_t h )
{
struct atom_table *table;
if (h)
{
table = (struct atom_table*)get_handle_obj( current->process, h,
0, &atom_table_ops );
}
else
{
if (!global_table && !(global_table = create_table( HASH_SIZE )))
return NULL;
table = (struct atom_table*)grab_object( global_table );
}
return table;
}
/* add a global atom */ /* add a global atom */
DECL_HANDLER(add_atom) DECL_HANDLER(add_atom)
{ {
struct atom_table **table_ptr = req->local ? &current->process->atom_table : &global_table; struct atom_table *table = get_table( req->table );
if (table)
if (!*table_ptr) *table_ptr = create_table(0);
if (*table_ptr)
{ {
const WCHAR *name = copy_request_name(); const WCHAR *name = copy_request_name();
if (name) reply->atom = add_atom( *table_ptr, name ); if (name) reply->atom = add_atom( table, name );
release_object( table );
} }
} }
/* delete a global atom */ /* delete a global atom */
DECL_HANDLER(delete_atom) DECL_HANDLER(delete_atom)
{ {
delete_atom( req->local ? current->process->atom_table : global_table, req->atom ); struct atom_table *table = get_table( req->table );
if (table)
{
delete_atom( table, req->atom );
release_object( table );
}
} }
/* find a global atom */ /* find a global atom */
DECL_HANDLER(find_atom) DECL_HANDLER(find_atom)
{ {
struct atom_table *table = get_table( req->table );
if (table)
{
const WCHAR *name = copy_request_name(); const WCHAR *name = copy_request_name();
if (name) if (name)
reply->atom = find_atom( req->local ? current->process->atom_table : global_table, name ); reply->atom = find_atom( table, name );
release_object( table );
}
} }
/* get global atom name */ /* get global atom name */
DECL_HANDLER(get_atom_name) DECL_HANDLER(get_atom_information)
{ {
struct atom_table *table = get_table( req->table );
if (table)
{
struct atom_entry *entry; struct atom_entry *entry;
size_t len = 0;
reply->count = -1; if ((entry = get_atom_entry( table, req->atom )))
if ((entry = get_atom_entry( req->local ? current->process->atom_table : global_table,
req->atom )))
{ {
reply->count = entry->count; size_t len = strlenW( entry->str ) * sizeof(WCHAR);
len = strlenW( entry->str ) * sizeof(WCHAR);
if (len <= get_reply_max_size()) set_reply_data( entry->str, len ); if (len <= get_reply_max_size()) set_reply_data( entry->str, len );
else set_error( STATUS_BUFFER_OVERFLOW ); else set_error( STATUS_BUFFER_OVERFLOW );
reply->count = entry->count;
reply->pinned = entry->pinned;
}
else reply->count = -1;
release_object( table );
}
}
/* set global atom name */
DECL_HANDLER(set_atom_information)
{
struct atom_table *table = get_table( req->table );
if (table)
{
struct atom_entry *entry;
if ((entry = get_atom_entry( table, req->atom )))
{
if (req->pinned) entry->pinned = 1;
}
release_object( table );
} }
} }
/* init the process atom table */ /* init a (local) atom table */
DECL_HANDLER(init_atom_table) DECL_HANDLER(init_atom_table)
{ {
if (!current->process->atom_table) struct atom_table* table;
current->process->atom_table = create_table( req->entries );
table = create_table( req->entries );
reply->table = alloc_handle( current->process, table, 0, FALSE);
release_object( table );
}
/* set global atom name */
DECL_HANDLER(empty_atom_table)
{
struct atom_table *table = get_table( req->table );
if (table)
{
int i;
struct atom_entry *entry;
for (i = 0; i <= table->last; i++)
{
entry = table->handles[i];
if (entry && (!entry->pinned || req->if_pinned))
{
if (entry->next) entry->next->prev = entry->prev;
if (entry->prev) entry->prev->next = entry->next;
else table->entries[entry->hash] = entry->next;
table->handles[i] = NULL;
free( entry );
}
}
release_object( table );
}
} }
...@@ -278,7 +278,6 @@ struct thread *create_process( int fd ) ...@@ -278,7 +278,6 @@ struct thread *create_process( int fd )
process->startup_info = NULL; process->startup_info = NULL;
process->idle_event = NULL; process->idle_event = NULL;
process->queue = NULL; process->queue = NULL;
process->atom_table = NULL;
process->peb = NULL; process->peb = NULL;
process->ldt_copy = NULL; process->ldt_copy = NULL;
process->exe.file = NULL; process->exe.file = NULL;
...@@ -422,7 +421,6 @@ static void process_destroy( struct object *obj ) ...@@ -422,7 +421,6 @@ static void process_destroy( struct object *obj )
list_remove( &process->entry ); list_remove( &process->entry );
if (process->idle_event) release_object( process->idle_event ); if (process->idle_event) release_object( process->idle_event );
if (process->queue) release_object( process->queue ); if (process->queue) release_object( process->queue );
if (process->atom_table) release_object( process->atom_table );
if (process->exe.file) release_object( process->exe.file ); if (process->exe.file) release_object( process->exe.file );
if (process->exe.filename) free( process->exe.filename ); if (process->exe.filename) free( process->exe.filename );
if (process->id) free_ptid( process->id ); if (process->id) free_ptid( process->id );
......
...@@ -72,7 +72,6 @@ struct process ...@@ -72,7 +72,6 @@ struct process
struct startup_info *startup_info; /* startup info while init is in progress */ struct startup_info *startup_info; /* startup info while init is in progress */
struct event *idle_event; /* event for input idle */ struct event *idle_event; /* event for input idle */
struct msg_queue *queue; /* main message queue */ struct msg_queue *queue; /* main message queue */
struct atom_table *atom_table; /* pointer to local atom table */
struct token *token; /* security token associated with this process */ struct token *token; /* security token associated with this process */
struct process_dll exe; /* main exe file */ struct process_dll exe; /* main exe file */
struct list dlls; /* list of loaded dlls */ struct list dlls; /* list of loaded dlls */
......
...@@ -1418,7 +1418,7 @@ enum char_info_mode ...@@ -1418,7 +1418,7 @@ enum char_info_mode
/* Add an atom */ /* Add an atom */
@REQ(add_atom) @REQ(add_atom)
int local; /* is atom in local process table? */ obj_handle_t table; /* which table to add atom to */
VARARG(name,unicode_str); /* atom name */ VARARG(name,unicode_str); /* atom name */
@REPLY @REPLY
atom_t atom; /* resulting atom */ atom_t atom; /* resulting atom */
...@@ -1427,33 +1427,51 @@ enum char_info_mode ...@@ -1427,33 +1427,51 @@ enum char_info_mode
/* Delete an atom */ /* Delete an atom */
@REQ(delete_atom) @REQ(delete_atom)
obj_handle_t table; /* which table to delete atom from */
atom_t atom; /* atom handle */ atom_t atom; /* atom handle */
int local; /* is atom in local process table? */
@END @END
/* Find an atom */ /* Find an atom */
@REQ(find_atom) @REQ(find_atom)
int local; /* is atom in local process table? */ obj_handle_t table; /* which table to find atom from */
VARARG(name,unicode_str); /* atom name */ VARARG(name,unicode_str); /* atom name */
@REPLY @REPLY
atom_t atom; /* atom handle */ atom_t atom; /* atom handle */
@END @END
/* Get an atom name */ /* Get information about an atom */
@REQ(get_atom_name) @REQ(get_atom_information)
obj_handle_t table; /* which table to find atom from */
atom_t atom; /* atom handle */ atom_t atom; /* atom handle */
int local; /* is atom in local process table? */
@REPLY @REPLY
int count; /* atom lock count */ int count; /* atom lock count */
int pinned; /* whether the atom has been pinned */
VARARG(name,unicode_str); /* atom name */ VARARG(name,unicode_str); /* atom name */
@END @END
/* Init the process atom table */ /* Set information about an atom */
@REQ(set_atom_information)
obj_handle_t table; /* which table to find atom from */
atom_t atom; /* atom handle */
int pinned; /* whether to bump atom information */
@END
/* Empty an atom table */
@REQ(empty_atom_table)
obj_handle_t table; /* which table to find atom from */
int if_pinned; /* whether to delete pinned atoms */
@END
/* Init an atom table */
@REQ(init_atom_table) @REQ(init_atom_table)
int entries; /* number of entries */ int entries; /* number of entries (only for local) */
@REPLY
obj_handle_t table; /* handle to the atom table */
@END @END
......
...@@ -216,7 +216,9 @@ DECL_HANDLER(get_selector_entry); ...@@ -216,7 +216,9 @@ DECL_HANDLER(get_selector_entry);
DECL_HANDLER(add_atom); DECL_HANDLER(add_atom);
DECL_HANDLER(delete_atom); DECL_HANDLER(delete_atom);
DECL_HANDLER(find_atom); DECL_HANDLER(find_atom);
DECL_HANDLER(get_atom_name); DECL_HANDLER(get_atom_information);
DECL_HANDLER(set_atom_information);
DECL_HANDLER(empty_atom_table);
DECL_HANDLER(init_atom_table); DECL_HANDLER(init_atom_table);
DECL_HANDLER(get_msg_queue); DECL_HANDLER(get_msg_queue);
DECL_HANDLER(set_queue_mask); DECL_HANDLER(set_queue_mask);
...@@ -412,7 +414,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -412,7 +414,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_add_atom, (req_handler)req_add_atom,
(req_handler)req_delete_atom, (req_handler)req_delete_atom,
(req_handler)req_find_atom, (req_handler)req_find_atom,
(req_handler)req_get_atom_name, (req_handler)req_get_atom_information,
(req_handler)req_set_atom_information,
(req_handler)req_empty_atom_table,
(req_handler)req_init_atom_table, (req_handler)req_init_atom_table,
(req_handler)req_get_msg_queue, (req_handler)req_get_msg_queue,
(req_handler)req_set_queue_mask, (req_handler)req_set_queue_mask,
......
...@@ -1758,7 +1758,7 @@ static void dump_get_selector_entry_reply( const struct get_selector_entry_reply ...@@ -1758,7 +1758,7 @@ static void dump_get_selector_entry_reply( const struct get_selector_entry_reply
static void dump_add_atom_request( const struct add_atom_request *req ) static void dump_add_atom_request( const struct add_atom_request *req )
{ {
fprintf( stderr, " local=%d,", req->local ); fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " name=" ); fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size ); dump_varargs_unicode_str( cur_size );
} }
...@@ -1770,13 +1770,13 @@ static void dump_add_atom_reply( const struct add_atom_reply *req ) ...@@ -1770,13 +1770,13 @@ static void dump_add_atom_reply( const struct add_atom_reply *req )
static void dump_delete_atom_request( const struct delete_atom_request *req ) static void dump_delete_atom_request( const struct delete_atom_request *req )
{ {
fprintf( stderr, " atom=%04x,", req->atom ); fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " local=%d", req->local ); fprintf( stderr, " atom=%04x", req->atom );
} }
static void dump_find_atom_request( const struct find_atom_request *req ) static void dump_find_atom_request( const struct find_atom_request *req )
{ {
fprintf( stderr, " local=%d,", req->local ); fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " name=" ); fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size ); dump_varargs_unicode_str( cur_size );
} }
...@@ -1786,24 +1786,43 @@ static void dump_find_atom_reply( const struct find_atom_reply *req ) ...@@ -1786,24 +1786,43 @@ static void dump_find_atom_reply( const struct find_atom_reply *req )
fprintf( stderr, " atom=%04x", req->atom ); fprintf( stderr, " atom=%04x", req->atom );
} }
static void dump_get_atom_name_request( const struct get_atom_name_request *req ) static void dump_get_atom_information_request( const struct get_atom_information_request *req )
{ {
fprintf( stderr, " atom=%04x,", req->atom ); fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " local=%d", req->local ); fprintf( stderr, " atom=%04x", req->atom );
} }
static void dump_get_atom_name_reply( const struct get_atom_name_reply *req ) static void dump_get_atom_information_reply( const struct get_atom_information_reply *req )
{ {
fprintf( stderr, " count=%d,", req->count ); fprintf( stderr, " count=%d,", req->count );
fprintf( stderr, " pinned=%d,", req->pinned );
fprintf( stderr, " name=" ); fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size ); dump_varargs_unicode_str( cur_size );
} }
static void dump_set_atom_information_request( const struct set_atom_information_request *req )
{
fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " atom=%04x,", req->atom );
fprintf( stderr, " pinned=%d", req->pinned );
}
static void dump_empty_atom_table_request( const struct empty_atom_table_request *req )
{
fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " if_pinned=%d", req->if_pinned );
}
static void dump_init_atom_table_request( const struct init_atom_table_request *req ) static void dump_init_atom_table_request( const struct init_atom_table_request *req )
{ {
fprintf( stderr, " entries=%d", req->entries ); fprintf( stderr, " entries=%d", req->entries );
} }
static void dump_init_atom_table_reply( const struct init_atom_table_reply *req )
{
fprintf( stderr, " table=%p", req->table );
}
static void dump_get_msg_queue_request( const struct get_msg_queue_request *req ) static void dump_get_msg_queue_request( const struct get_msg_queue_request *req )
{ {
} }
...@@ -2885,7 +2904,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -2885,7 +2904,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_add_atom_request, (dump_func)dump_add_atom_request,
(dump_func)dump_delete_atom_request, (dump_func)dump_delete_atom_request,
(dump_func)dump_find_atom_request, (dump_func)dump_find_atom_request,
(dump_func)dump_get_atom_name_request, (dump_func)dump_get_atom_information_request,
(dump_func)dump_set_atom_information_request,
(dump_func)dump_empty_atom_table_request,
(dump_func)dump_init_atom_table_request, (dump_func)dump_init_atom_table_request,
(dump_func)dump_get_msg_queue_request, (dump_func)dump_get_msg_queue_request,
(dump_func)dump_set_queue_mask_request, (dump_func)dump_set_queue_mask_request,
...@@ -3078,8 +3099,10 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -3078,8 +3099,10 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_add_atom_reply, (dump_func)dump_add_atom_reply,
(dump_func)0, (dump_func)0,
(dump_func)dump_find_atom_reply, (dump_func)dump_find_atom_reply,
(dump_func)dump_get_atom_name_reply, (dump_func)dump_get_atom_information_reply,
(dump_func)0,
(dump_func)0, (dump_func)0,
(dump_func)dump_init_atom_table_reply,
(dump_func)dump_get_msg_queue_reply, (dump_func)dump_get_msg_queue_reply,
(dump_func)dump_set_queue_mask_reply, (dump_func)dump_set_queue_mask_reply,
(dump_func)dump_get_queue_status_reply, (dump_func)dump_get_queue_status_reply,
...@@ -3271,7 +3294,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -3271,7 +3294,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"add_atom", "add_atom",
"delete_atom", "delete_atom",
"find_atom", "find_atom",
"get_atom_name", "get_atom_information",
"set_atom_information",
"empty_atom_table",
"init_atom_table", "init_atom_table",
"get_msg_queue", "get_msg_queue",
"set_queue_mask", "set_queue_mask",
......
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