Commit 43a27e36 authored by Turchanov Sergei's avatar Turchanov Sergei Committed by Alexandre Julliard

Implemented local atoms in the server.

parent 84bde6a4
......@@ -1117,38 +1117,49 @@ struct get_selector_entry_request
};
/* Add a global atom */
/* Add an atom */
struct add_atom_request
{
IN int local; /* is atom in local process table? */
OUT int atom; /* resulting atom */
IN WCHAR name[1]; /* atom name */
};
/* Delete a global atom */
/* Delete an atom */
struct delete_atom_request
{
IN int atom; /* atom handle */
IN int local; /* is atom in local process table? */
};
/* Find a global atom */
/* Find an atom */
struct find_atom_request
{
IN int local; /* is atom in local process table? */
OUT int atom; /* atom handle */
IN WCHAR name[1]; /* atom name */
};
/* Get a global atom name */
/* Get an atom name */
struct get_atom_name_request
{
IN int atom; /* atom handle */
IN int local; /* is atom in local process table? */
OUT int count; /* atom lock count */
OUT WCHAR name[1]; /* atom name */
};
/* Init the process atom table */
struct init_atom_table_request
{
IN int entries; /* number of entries */
};
/* Get the message queue of the current thread */
struct get_msg_queue_request
{
......@@ -1279,13 +1290,14 @@ enum request
REQ_DELETE_ATOM,
REQ_FIND_ATOM,
REQ_GET_ATOM_NAME,
REQ_INIT_ATOM_TABLE,
REQ_GET_MSG_QUEUE,
REQ_WAKE_QUEUE,
REQ_WAIT_INPUT_IDLE,
REQ_NB_REQUESTS
};
#define SERVER_PROTOCOL_VERSION 13
#define SERVER_PROTOCOL_VERSION 14
/* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */
......
......@@ -486,7 +486,7 @@ import ntdll.dll
468 stdcall HeapUnlock(long) HeapUnlock
469 stdcall HeapValidate(long long ptr) HeapValidate
470 stdcall HeapWalk(long ptr) HeapWalk
471 stub InitAtomTable
471 stdcall InitAtomTable(long) InitAtomTable
472 stdcall InitializeCriticalSection(ptr) InitializeCriticalSection
473 stdcall InterlockedDecrement(ptr) InterlockedDecrement
474 stdcall InterlockedExchange(ptr long) InterlockedExchange
......
......@@ -12,8 +12,12 @@
#include "unicode.h"
#include "request.h"
#include "object.h"
#include "process.h"
#define HASH_SIZE 37
#define MIN_HASH_SIZE 4
#define MAX_HASH_SIZE 0x200
#define MAX_ATOM_LEN 255
#define MAX_ATOMS 0x4000
......@@ -33,10 +37,10 @@ struct atom_table
int count; /* count of atom handles */
int last; /* last handle in-use */
struct atom_entry **handles; /* atom handles */
struct atom_entry *entries[HASH_SIZE]; /* hash table entries */
int entries_count; /* humber of hash entries */
struct atom_entry **entries; /* hash table entries */
};
static void atom_table_dump( struct object *obj, int verbose );
static void atom_table_destroy( struct object *obj );
......@@ -72,17 +76,26 @@ static const WCHAR *copy_name( const WCHAR *str )
}
/* create an atom table */
static struct atom_table *create_table(void)
static struct atom_table *create_table(int entries_count)
{
struct atom_table *table;
if ((table = alloc_object( &atom_table_ops, -1 )))
{
if ((entries_count < MIN_HASH_SIZE) ||
(entries_count > MAX_HASH_SIZE)) entries_count = HASH_SIZE;
table->entries_count = entries_count;
if (!(table->entries = malloc( sizeof(*table->entries) * table->entries_count )))
{
set_error( STATUS_NO_MEMORY );
goto fail;
}
memset( table->entries, 0, sizeof(*table->entries) * table->entries_count );
table->count = 64;
table->last = -1;
memset( table->entries, 0, sizeof(table->entries) );
if ((table->handles = mem_alloc( sizeof(*table->handles) * table->count )))
return table;
fail:
release_object( table );
table = NULL;
}
......@@ -127,12 +140,12 @@ static int add_atom_entry( struct atom_table *table, struct atom_entry *entry )
}
/* compute the hash code for a string */
static int atom_hash( const WCHAR *str )
static int atom_hash( struct atom_table *table, const WCHAR *str )
{
int i;
WCHAR hash = 0;
for (i = 0; str[i]; i++) hash ^= towupper(str[i]) + i;
return hash % HASH_SIZE;
return hash % table->entries_count;
}
/* dump an atom table */
......@@ -142,7 +155,8 @@ static void atom_table_dump( struct object *obj, int verbose )
struct atom_table *table = (struct atom_table *)obj;
assert( obj->ops == &atom_table_ops );
fprintf( stderr, "Atom table size=%d\n", table->last + 1 );
fprintf( stderr, "Atom table size=%d entries=%d\n",
table->last + 1, table->entries_count );
if (!verbose) return;
for (i = 0; i <= table->last; i++)
{
......@@ -160,8 +174,12 @@ static void atom_table_destroy( struct object *obj )
int i;
struct atom_table *table = (struct atom_table *)obj;
assert( obj->ops == &atom_table_ops );
for (i = 0; i <= table->last; i++) free( table->handles[i] );
free( table->handles );
if (table->handles)
{
for (i = 0; i <= table->last; i++) free( table->handles[i] );
free( table->handles );
}
if (table->entries) free( table->entries );
}
/* find an atom entry in its hash list */
......@@ -186,7 +204,7 @@ void close_atom_table(void)
static int add_atom( struct atom_table *table, const WCHAR *str )
{
struct atom_entry *entry;
int hash = atom_hash( str );
int hash = atom_hash( table, str );
int atom = -1;
if (!*str)
......@@ -236,7 +254,7 @@ static int find_atom( struct atom_table *table, const WCHAR *str )
{
struct atom_entry *entry;
if (table && ((entry = find_atom_entry( table, str, atom_hash(str) )))) return entry->atom;
if (table && ((entry = find_atom_entry( table, str, atom_hash(table, str) )))) return entry->atom;
if (!*str) set_error( STATUS_OBJECT_NAME_INVALID );
else set_error( STATUS_OBJECT_NAME_NOT_FOUND );
return -1;
......@@ -258,25 +276,37 @@ static int get_atom_name( struct atom_table *table, int atom, WCHAR *str )
/* add a global atom */
DECL_HANDLER(add_atom)
{
if (!global_table) global_table = create_table();
if (global_table) req->atom = add_atom( global_table, copy_name( req->name ) );
struct atom_table **table_ptr = req->local ? &current->process->atom_table : &global_table;
if (!*table_ptr) *table_ptr = create_table(0);
if (*table_ptr) req->atom = add_atom( *table_ptr, copy_name( req->name ) );
}
/* delete a global atom */
DECL_HANDLER(delete_atom)
{
delete_atom( global_table, req->atom );
delete_atom( req->local ? current->process->atom_table : global_table,
req->atom );
}
/* find a global atom */
DECL_HANDLER(find_atom)
{
req->atom = find_atom( global_table, copy_name( req->name ) );
req->atom = find_atom( req->local ? current->process->atom_table : global_table,
copy_name( req->name ) );
}
/* get global atom name */
DECL_HANDLER(get_atom_name)
{
req->name[0] = 0;
req->count = get_atom_name( global_table, req->atom, req->name );
req->count = get_atom_name( req->local ? current->process->atom_table : global_table,
req->atom, req->name );
}
/* init the process atom table */
DECL_HANDLER(init_atom_table)
{
if (!current->process->atom_table)
current->process->atom_table = create_table( req->entries );
}
......@@ -169,6 +169,7 @@ struct thread *create_process( int fd )
process->init_event = NULL;
process->idle_event = NULL;
process->queue = NULL;
process->atom_table = NULL;
process->ldt_copy = NULL;
process->ldt_flags = NULL;
process->exe.next = NULL;
......@@ -288,6 +289,7 @@ static void process_destroy( struct object *obj )
if (process->init_event) release_object( process->init_event );
if (process->idle_event) release_object( process->idle_event );
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 );
}
......
......@@ -14,6 +14,7 @@
#include "object.h"
struct msg_queue;
struct atom_table;
/* process structures */
......@@ -49,6 +50,7 @@ struct process
struct event *init_event; /* event for init done */
struct event *idle_event; /* event for input idle */
struct msg_queue *queue; /* main message queue */
struct atom_table *atom_table; /* pointer to local atom table */
struct process_dll exe; /* main exe file */
void *ldt_copy; /* pointer to LDT copy in client addr space */
void *ldt_flags; /* pointer to LDT flags in client addr space */
......
......@@ -173,6 +173,7 @@ DECL_HANDLER(add_atom);
DECL_HANDLER(delete_atom);
DECL_HANDLER(find_atom);
DECL_HANDLER(get_atom_name);
DECL_HANDLER(init_atom_table);
DECL_HANDLER(get_msg_queue);
DECL_HANDLER(wake_queue);
DECL_HANDLER(wait_input_idle);
......@@ -285,6 +286,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_delete_atom,
(req_handler)req_find_atom,
(req_handler)req_get_atom_name,
(req_handler)req_init_atom_table,
(req_handler)req_get_msg_queue,
(req_handler)req_wake_queue,
(req_handler)req_wait_input_idle,
......
......@@ -1297,6 +1297,7 @@ static void dump_get_selector_entry_reply( const struct get_selector_entry_reque
static void dump_add_atom_request( const struct add_atom_request *req )
{
fprintf( stderr, " local=%d,", req->local );
fprintf( stderr, " name=" );
dump_unicode_string( req, req->name );
}
......@@ -1308,11 +1309,13 @@ static void dump_add_atom_reply( const struct add_atom_request *req )
static void dump_delete_atom_request( const struct delete_atom_request *req )
{
fprintf( stderr, " atom=%d", req->atom );
fprintf( stderr, " atom=%d,", req->atom );
fprintf( stderr, " local=%d", req->local );
}
static void dump_find_atom_request( const struct find_atom_request *req )
{
fprintf( stderr, " local=%d,", req->local );
fprintf( stderr, " name=" );
dump_unicode_string( req, req->name );
}
......@@ -1324,7 +1327,8 @@ static void dump_find_atom_reply( const struct find_atom_request *req )
static void dump_get_atom_name_request( const struct get_atom_name_request *req )
{
fprintf( stderr, " atom=%d", req->atom );
fprintf( stderr, " atom=%d,", req->atom );
fprintf( stderr, " local=%d", req->local );
}
static void dump_get_atom_name_reply( const struct get_atom_name_request *req )
......@@ -1334,6 +1338,11 @@ static void dump_get_atom_name_reply( const struct get_atom_name_request *req )
dump_unicode_string( req, req->name );
}
static void dump_init_atom_table_request( const struct init_atom_table_request *req )
{
fprintf( stderr, " entries=%d", req->entries );
}
static void dump_get_msg_queue_request( const struct get_msg_queue_request *req )
{
}
......@@ -1464,6 +1473,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_delete_atom_request,
(dump_func)dump_find_atom_request,
(dump_func)dump_get_atom_name_request,
(dump_func)dump_init_atom_table_request,
(dump_func)dump_get_msg_queue_request,
(dump_func)dump_wake_queue_request,
(dump_func)dump_wait_input_idle_request,
......@@ -1573,6 +1583,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)0,
(dump_func)dump_find_atom_reply,
(dump_func)dump_get_atom_name_reply,
(dump_func)0,
(dump_func)dump_get_msg_queue_reply,
(dump_func)0,
(dump_func)dump_wait_input_idle_reply,
......@@ -1682,6 +1693,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"delete_atom",
"find_atom",
"get_atom_name",
"init_atom_table",
"get_msg_queue",
"wake_queue",
"wait_input_idle",
......
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