Commit 526a28de authored by Alexandre Julliard's avatar Alexandre Julliard

Added support for multiple object namespaces, and a bunch functions

for managing linked lists.
parent c401270d
...@@ -65,7 +65,7 @@ struct event *create_event( const WCHAR *name, size_t len, ...@@ -65,7 +65,7 @@ struct event *create_event( const WCHAR *name, size_t len,
{ {
struct event *event; struct event *event;
if ((event = create_named_object( &event_ops, name, len ))) if ((event = create_named_object( sync_namespace, &event_ops, name, len )))
{ {
if (get_error() != STATUS_OBJECT_NAME_COLLISION) if (get_error() != STATUS_OBJECT_NAME_COLLISION)
{ {
...@@ -145,7 +145,7 @@ DECL_HANDLER(create_event) ...@@ -145,7 +145,7 @@ DECL_HANDLER(create_event)
/* open a handle to an event */ /* open a handle to an event */
DECL_HANDLER(open_event) DECL_HANDLER(open_event)
{ {
reply->handle = open_object( get_req_data(), get_req_data_size(), reply->handle = open_object( sync_namespace, get_req_data(), get_req_data_size(),
&event_ops, req->access, req->inherit ); &event_ops, req->access, req->inherit );
} }
......
...@@ -154,7 +154,7 @@ static void handle_table_destroy( struct object *obj ) ...@@ -154,7 +154,7 @@ static void handle_table_destroy( struct object *obj )
} }
/* allocate a new handle table */ /* allocate a new handle table */
struct object *alloc_handle_table( struct process *process, int count ) struct handle_table *alloc_handle_table( struct process *process, int count )
{ {
struct handle_table *table; struct handle_table *table;
...@@ -165,7 +165,7 @@ struct object *alloc_handle_table( struct process *process, int count ) ...@@ -165,7 +165,7 @@ struct object *alloc_handle_table( struct process *process, int count )
table->count = count; table->count = count;
table->last = -1; table->last = -1;
table->free = 0; table->free = 0;
if ((table->entries = mem_alloc( count * sizeof(*table->entries) ))) return &table->obj; if ((table->entries = mem_alloc( count * sizeof(*table->entries) ))) return table;
release_object( table ); release_object( table );
return NULL; return NULL;
} }
...@@ -213,7 +213,7 @@ static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned ...@@ -213,7 +213,7 @@ static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned
/* return the handle, or 0 on error */ /* return the handle, or 0 on error */
obj_handle_t alloc_handle( struct process *process, void *obj, unsigned int access, int inherit ) obj_handle_t alloc_handle( struct process *process, void *obj, unsigned int access, int inherit )
{ {
struct handle_table *table = (struct handle_table *)process->handles; struct handle_table *table = process->handles;
assert( table ); assert( table );
assert( !(access & RESERVED_ALL) ); assert( !(access & RESERVED_ALL) );
...@@ -236,7 +236,7 @@ static obj_handle_t alloc_global_handle( void *obj, unsigned int access ) ...@@ -236,7 +236,7 @@ static obj_handle_t alloc_global_handle( void *obj, unsigned int access )
/* return a handle entry, or NULL if the handle is invalid */ /* return a handle entry, or NULL if the handle is invalid */
static struct handle_entry *get_handle( struct process *process, obj_handle_t handle ) static struct handle_entry *get_handle( struct process *process, obj_handle_t handle )
{ {
struct handle_table *table = (struct handle_table *)process->handles; struct handle_table *table = process->handles;
struct handle_entry *entry; struct handle_entry *entry;
int index; int index;
...@@ -281,9 +281,9 @@ static void shrink_handle_table( struct handle_table *table ) ...@@ -281,9 +281,9 @@ static void shrink_handle_table( struct handle_table *table )
/* copy the handle table of the parent process */ /* copy the handle table of the parent process */
/* return 1 if OK, 0 on error */ /* return 1 if OK, 0 on error */
struct object *copy_handle_table( struct process *process, struct process *parent ) struct handle_table *copy_handle_table( struct process *process, struct process *parent )
{ {
struct handle_table *parent_table = (struct handle_table *)parent->handles; struct handle_table *parent_table = parent->handles;
struct handle_table *table; struct handle_table *table;
int i; int i;
...@@ -307,7 +307,7 @@ struct object *copy_handle_table( struct process *process, struct process *paren ...@@ -307,7 +307,7 @@ struct object *copy_handle_table( struct process *process, struct process *paren
} }
/* attempt to shrink the table */ /* attempt to shrink the table */
shrink_handle_table( table ); shrink_handle_table( table );
return &table->obj; return table;
} }
/* close a handle and decrement the refcount of the associated object */ /* close a handle and decrement the refcount of the associated object */
...@@ -329,7 +329,7 @@ int close_handle( struct process *process, obj_handle_t handle, int *fd ) ...@@ -329,7 +329,7 @@ int close_handle( struct process *process, obj_handle_t handle, int *fd )
if (fd) *fd = entry->fd; if (fd) *fd = entry->fd;
else if (entry->fd != -1) return 1; /* silently ignore close attempt if we cannot close the fd */ else if (entry->fd != -1) return 1; /* silently ignore close attempt if we cannot close the fd */
entry->fd = -1; entry->fd = -1;
table = handle_is_global(handle) ? global_table : (struct handle_table *)process->handles; table = handle_is_global(handle) ? global_table : process->handles;
if (entry < table->entries + table->free) table->free = entry - table->entries; if (entry < table->entries + table->free) table->free = entry - table->entries;
if (entry == table->entries + table->last) shrink_handle_table( table ); if (entry == table->entries + table->last) shrink_handle_table( table );
release_object( obj ); release_object( obj );
...@@ -400,10 +400,28 @@ int get_handle_fd( struct process *process, obj_handle_t handle, unsigned int ac ...@@ -400,10 +400,28 @@ int get_handle_fd( struct process *process, obj_handle_t handle, unsigned int ac
return entry->fd; return entry->fd;
} }
/* find the first inherited handle of the given type */
/* this is needed for window stations and desktops (don't ask...) */
obj_handle_t find_inherited_handle( struct process *process, const struct object_ops *ops )
{
struct handle_table *table = process->handles;
struct handle_entry *ptr;
int i;
if (!table) return 0;
for (i = 0, ptr = table->entries; i <= table->last; i++, ptr++)
{
if (!ptr->ptr) continue;
if (ptr->ptr->ops != ops) continue;
if (ptr->access & RESERVED_INHERIT) return index_to_handle(i);
}
return 0;
}
/* get/set the handle reserved flags */ /* get/set the handle reserved flags */
/* return the old flags (or -1 on error) */ /* return the old flags (or -1 on error) */
static int set_handle_info( struct process *process, obj_handle_t handle, int set_handle_info( struct process *process, obj_handle_t handle, int mask, int flags, int *fd )
int mask, int flags, int *fd )
{ {
struct handle_entry *entry; struct handle_entry *entry;
unsigned int old_access; unsigned int old_access;
...@@ -454,11 +472,11 @@ obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, str ...@@ -454,11 +472,11 @@ obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, str
} }
/* open a new handle to an existing object */ /* open a new handle to an existing object */
obj_handle_t open_object( const WCHAR *name, size_t len, const struct object_ops *ops, obj_handle_t open_object( const struct namespace *namespace, const WCHAR *name, size_t len,
unsigned int access, int inherit ) const struct object_ops *ops, unsigned int access, int inherit )
{ {
obj_handle_t handle = 0; obj_handle_t handle = 0;
struct object *obj = find_object( name, len ); struct object *obj = find_object( namespace, name, len );
if (obj) if (obj)
{ {
if (ops && obj->ops != ops) if (ops && obj->ops != ops)
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
struct process; struct process;
struct object_ops; struct object_ops;
struct namespace;
/* handle functions */ /* handle functions */
...@@ -38,12 +39,14 @@ extern int close_handle( struct process *process, obj_handle_t handle, int *fd ) ...@@ -38,12 +39,14 @@ extern int close_handle( struct process *process, obj_handle_t handle, int *fd )
extern struct object *get_handle_obj( struct process *process, obj_handle_t handle, extern struct object *get_handle_obj( struct process *process, obj_handle_t handle,
unsigned int access, const struct object_ops *ops ); unsigned int access, const struct object_ops *ops );
extern int get_handle_fd( struct process *process, obj_handle_t handle, unsigned int access ); extern int get_handle_fd( struct process *process, obj_handle_t handle, unsigned int access );
extern int set_handle_info( struct process *process, obj_handle_t handle, int mask, int flags, int *fd );
extern obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst, extern obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst,
unsigned int access, int inherit, int options ); unsigned int access, int inherit, int options );
extern obj_handle_t open_object( const WCHAR *name, size_t len, const struct object_ops *ops, extern obj_handle_t open_object( const struct namespace *namespace, const WCHAR *name, size_t len,
unsigned int access, int inherit ); const struct object_ops *ops, unsigned int access, int inherit );
extern struct object *alloc_handle_table( struct process *process, int count ); extern obj_handle_t find_inherited_handle( struct process *process, const struct object_ops *ops );
extern struct object *copy_handle_table( struct process *process, struct process *parent ); extern struct handle_table *alloc_handle_table( struct process *process, int count );
extern struct handle_table *copy_handle_table( struct process *process, struct process *parent );
extern void close_global_handles(void); extern void close_global_handles(void);
#endif /* __WINE_SERVER_HANDLE_H */ #endif /* __WINE_SERVER_HANDLE_H */
/*
* Linked lists support
*
* Copyright (C) 2002 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __WINE_SERVER_LIST_H
#define __WINE_SERVER_LIST_H
struct list
{
struct list *next;
struct list *prev;
};
/* add element at the head of the list */
inline static void list_add_head( struct list *list, struct list *elem )
{
elem->next = list->next;
elem->prev = list;
list->next->prev = elem;
list->next = elem;
}
/* add element at the tail of the list */
inline static void list_add_tail( struct list *list, struct list *elem )
{
elem->next = list;
elem->prev = list->prev;
list->prev->next = elem;
list->prev = elem;
}
/* remove an element from its list */
inline static void list_remove( struct list *elem )
{
elem->next->prev = elem->prev;
elem->prev->next = elem->next;
}
/* initialize a list */
inline static void list_init( struct list *list )
{
list->next = list->prev = list;
}
/* iterate through the list */
#define LIST_FOR_EACH(cursor,list) \
for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
/* macros for statically initialized lists */
#define LIST_INIT(list) { &(list), &(list) }
/* get pointer to object containing list element */
#define LIST_ENTRY(elem, type, field) \
((type *)((char *)(elem) - (unsigned int)(&((type *)0)->field)))
#endif /* __WINE_SERVER_LIST_H */
...@@ -36,6 +36,9 @@ int debug_level = 0; ...@@ -36,6 +36,9 @@ int debug_level = 0;
int master_socket_timeout = 3; /* master socket timeout in seconds, default is 3 s */ int master_socket_timeout = 3; /* master socket timeout in seconds, default is 3 s */
const char *server_argv0; const char *server_argv0;
/* name space for synchronization objects */
struct namespace *sync_namespace;
/* parse-line args */ /* parse-line args */
/* FIXME: should probably use getopt, and add a (more complete?) help option */ /* FIXME: should probably use getopt, and add a (more complete?) help option */
...@@ -118,6 +121,7 @@ int main( int argc, char *argv[] ) ...@@ -118,6 +121,7 @@ int main( int argc, char *argv[] )
signal_init(); signal_init();
sock_init(); sock_init();
open_master_socket(); open_master_socket();
sync_namespace = create_namespace( 37, TRUE );
setvbuf( stderr, NULL, _IOLBF, 0 ); setvbuf( stderr, NULL, _IOLBF, 0 );
if (debug_level) fprintf( stderr, "wineserver: starting (pid=%ld)\n", (long) getpid() ); if (debug_level) fprintf( stderr, "wineserver: starting (pid=%ld)\n", (long) getpid() );
......
...@@ -263,7 +263,7 @@ static struct object *create_mapping( int size_high, int size_low, int protect, ...@@ -263,7 +263,7 @@ static struct object *create_mapping( int size_high, int size_low, int protect,
if (!page_mask) init_page_size(); if (!page_mask) init_page_size();
if (!(mapping = create_named_object( &mapping_ops, name, len ))) if (!(mapping = create_named_object( sync_namespace, &mapping_ops, name, len )))
return NULL; return NULL;
if (get_error() == STATUS_OBJECT_NAME_COLLISION) if (get_error() == STATUS_OBJECT_NAME_COLLISION)
return &mapping->obj; /* Nothing else to do */ return &mapping->obj; /* Nothing else to do */
...@@ -383,7 +383,7 @@ DECL_HANDLER(create_mapping) ...@@ -383,7 +383,7 @@ DECL_HANDLER(create_mapping)
/* open a handle to a mapping */ /* open a handle to a mapping */
DECL_HANDLER(open_mapping) DECL_HANDLER(open_mapping)
{ {
reply->handle = open_object( get_req_data(), get_req_data_size(), reply->handle = open_object( sync_namespace, get_req_data(), get_req_data_size(),
&mapping_ops, req->access, req->inherit ); &mapping_ops, req->access, req->inherit );
} }
......
...@@ -68,7 +68,7 @@ static struct mutex *create_mutex( const WCHAR *name, size_t len, int owned ) ...@@ -68,7 +68,7 @@ static struct mutex *create_mutex( const WCHAR *name, size_t len, int owned )
{ {
struct mutex *mutex; struct mutex *mutex;
if ((mutex = create_named_object( &mutex_ops, name, len ))) if ((mutex = create_named_object( sync_namespace, &mutex_ops, name, len )))
{ {
if (get_error() != STATUS_OBJECT_NAME_COLLISION) if (get_error() != STATUS_OBJECT_NAME_COLLISION)
{ {
...@@ -169,7 +169,7 @@ DECL_HANDLER(create_mutex) ...@@ -169,7 +169,7 @@ DECL_HANDLER(create_mutex)
/* open a handle to a mutex */ /* open a handle to a mutex */
DECL_HANDLER(open_mutex) DECL_HANDLER(open_mutex)
{ {
reply->handle = open_object( get_req_data(), get_req_data_size(), reply->handle = open_object( sync_namespace, get_req_data(), get_req_data_size(),
&mutex_ops, req->access, req->inherit ); &mutex_ops, req->access, req->inherit );
} }
......
...@@ -222,7 +222,7 @@ static struct named_pipe *create_named_pipe( const WCHAR *name, size_t len ) ...@@ -222,7 +222,7 @@ static struct named_pipe *create_named_pipe( const WCHAR *name, size_t len )
{ {
struct named_pipe *pipe; struct named_pipe *pipe;
if ((pipe = create_named_object( &named_pipe_ops, name, len ))) if ((pipe = create_named_object( sync_namespace, &named_pipe_ops, name, len )))
{ {
if (get_error() != STATUS_OBJECT_NAME_COLLISION) if (get_error() != STATUS_OBJECT_NAME_COLLISION)
{ {
......
...@@ -30,32 +30,37 @@ ...@@ -30,32 +30,37 @@
#include "thread.h" #include "thread.h"
#include "unicode.h" #include "unicode.h"
#include "list.h"
struct object_name struct object_name
{ {
struct object_name *next; struct list entry; /* entry in the hash list */
struct object_name *prev;
struct object *obj; struct object *obj;
size_t len; size_t len;
WCHAR name[1]; WCHAR name[1];
}; };
#define NAME_HASH_SIZE 37 struct namespace
{
unsigned int hash_size; /* size of hash table */
int case_sensitive; /* are names case sensitive? */
struct list names[1]; /* array of hash entry lists */
};
static struct object_name *names[NAME_HASH_SIZE];
#ifdef DEBUG_OBJECTS #ifdef DEBUG_OBJECTS
static struct object *first; static struct list object_list = LIST_INIT(object_list);
void dump_objects(void) void dump_objects(void)
{ {
struct object *ptr = first; struct list *p;
while (ptr)
LIST_FOR_EACH( p, &object_list )
{ {
struct object *ptr = LIST_ENTRY( p, struct object, obj_list );
fprintf( stderr, "%p:%d: ", ptr, ptr->refcount ); fprintf( stderr, "%p:%d: ", ptr, ptr->refcount );
ptr->ops->dump( ptr, 1 ); ptr->ops->dump( ptr, 1 );
ptr = ptr->next;
} }
} }
#endif #endif
...@@ -83,12 +88,13 @@ void *memdup( const void *data, size_t len ) ...@@ -83,12 +88,13 @@ void *memdup( const void *data, size_t len )
/*****************************************************************/ /*****************************************************************/
static int get_name_hash( const WCHAR *name, size_t len ) static int get_name_hash( const struct namespace *namespace, const WCHAR *name, size_t len )
{ {
WCHAR hash = 0; WCHAR hash = 0;
len /= sizeof(WCHAR); len /= sizeof(WCHAR);
while (len--) hash ^= *name++; if (namespace->case_sensitive) while (len--) hash ^= *name++;
return hash % NAME_HASH_SIZE; else while (len--) hash ^= tolowerW(*name++);
return hash % namespace->hash_size;
} }
/* allocate a name for an object */ /* allocate a name for an object */
...@@ -108,31 +114,18 @@ static struct object_name *alloc_name( const WCHAR *name, size_t len ) ...@@ -108,31 +114,18 @@ static struct object_name *alloc_name( const WCHAR *name, size_t len )
static void free_name( struct object *obj ) static void free_name( struct object *obj )
{ {
struct object_name *ptr = obj->name; struct object_name *ptr = obj->name;
if (ptr->next) ptr->next->prev = ptr->prev; list_remove( &ptr->entry );
if (ptr->prev) ptr->prev->next = ptr->next;
else
{
int hash;
for (hash = 0; hash < NAME_HASH_SIZE; hash++)
if (names[hash] == ptr)
{
names[hash] = ptr->next;
break;
}
}
free( ptr ); free( ptr );
} }
/* set the name of an existing object */ /* set the name of an existing object */
static void set_object_name( struct object *obj, struct object_name *ptr ) static void set_object_name( struct namespace *namespace,
struct object *obj, struct object_name *ptr )
{ {
int hash = get_name_hash( ptr->name, ptr->len ); int hash = get_name_hash( namespace, ptr->name, ptr->len );
if ((ptr->next = names[hash]) != NULL) ptr->next->prev = ptr; list_add_head( &namespace->names[hash], &ptr->entry );
ptr->obj = obj; ptr->obj = obj;
ptr->prev = NULL;
names[hash] = ptr;
assert( !obj->name );
obj->name = ptr; obj->name = ptr;
} }
...@@ -157,9 +150,7 @@ void *alloc_object( const struct object_ops *ops, int fd ) ...@@ -157,9 +150,7 @@ void *alloc_object( const struct object_ops *ops, int fd )
return NULL; return NULL;
} }
#ifdef DEBUG_OBJECTS #ifdef DEBUG_OBJECTS
obj->prev = NULL; list_add_head( &object_list, &obj->obj_list );
if ((obj->next = first) != NULL) obj->next->prev = obj;
first = obj;
#endif #endif
return obj; return obj;
} }
...@@ -167,17 +158,16 @@ void *alloc_object( const struct object_ops *ops, int fd ) ...@@ -167,17 +158,16 @@ void *alloc_object( const struct object_ops *ops, int fd )
return NULL; return NULL;
} }
void *create_named_object( const struct object_ops *ops, const WCHAR *name, size_t len ) void *create_named_object( struct namespace *namespace, const struct object_ops *ops,
const WCHAR *name, size_t len )
{ {
struct object *obj; struct object *obj;
struct object_name *name_ptr; struct object_name *name_ptr;
if (!name || !len) return alloc_object( ops, -1 ); if (!name || !len) return alloc_object( ops, -1 );
if (!(name_ptr = alloc_name( name, len ))) return NULL;
if ((obj = find_object( name_ptr->name, name_ptr->len ))) if ((obj = find_object( namespace, name, len )))
{ {
free( name_ptr ); /* we no longer need it */
if (obj->ops == ops) if (obj->ops == ops)
{ {
set_error( STATUS_OBJECT_NAME_COLLISION ); set_error( STATUS_OBJECT_NAME_COLLISION );
...@@ -186,9 +176,10 @@ void *create_named_object( const struct object_ops *ops, const WCHAR *name, size ...@@ -186,9 +176,10 @@ void *create_named_object( const struct object_ops *ops, const WCHAR *name, size
set_error( STATUS_OBJECT_TYPE_MISMATCH ); set_error( STATUS_OBJECT_TYPE_MISMATCH );
return NULL; return NULL;
} }
if (!(name_ptr = alloc_name( name, len ))) return NULL;
if ((obj = alloc_object( ops, -1 ))) if ((obj = alloc_object( ops, -1 )))
{ {
set_object_name( obj, name_ptr ); set_object_name( namespace, obj, name_ptr );
clear_error(); clear_error();
} }
else free( name_ptr ); else free( name_ptr );
...@@ -231,9 +222,7 @@ void release_object( void *ptr ) ...@@ -231,9 +222,7 @@ void release_object( void *ptr )
if (obj->select != -1) remove_select_user( obj ); if (obj->select != -1) remove_select_user( obj );
if (obj->fd != -1) close( obj->fd ); if (obj->fd != -1) close( obj->fd );
#ifdef DEBUG_OBJECTS #ifdef DEBUG_OBJECTS
if (obj->next) obj->next->prev = obj->prev; list_remove( &obj->obj_list );
if (obj->prev) obj->prev->next = obj->next;
else first = obj->next;
memset( obj, 0xaa, obj->ops->size ); memset( obj, 0xaa, obj->ops->size );
#endif #endif
free( obj ); free( obj );
...@@ -241,19 +230,50 @@ void release_object( void *ptr ) ...@@ -241,19 +230,50 @@ void release_object( void *ptr )
} }
/* find an object by its name; the refcount is incremented */ /* find an object by its name; the refcount is incremented */
struct object *find_object( const WCHAR *name, size_t len ) struct object *find_object( const struct namespace *namespace, const WCHAR *name, size_t len )
{ {
struct object_name *ptr; const struct list *list, *p;
if (!name || !len) return NULL; if (!name || !len) return NULL;
for (ptr = names[ get_name_hash( name, len ) ]; ptr; ptr = ptr->next)
list = &namespace->names[ get_name_hash( namespace, name, len ) ];
if (namespace->case_sensitive)
{
LIST_FOR_EACH( p, list )
{ {
struct object_name *ptr = LIST_ENTRY( p, struct object_name, entry );
if (ptr->len != len) continue; if (ptr->len != len) continue;
if (!memcmp( ptr->name, name, len )) return grab_object( ptr->obj ); if (!memcmp( ptr->name, name, len )) return grab_object( ptr->obj );
} }
}
else
{
LIST_FOR_EACH( p, list )
{
struct object_name *ptr = LIST_ENTRY( p, struct object_name, entry );
if (ptr->len != len) continue;
if (!strncmpiW( ptr->name, name, len/sizeof(WCHAR) )) return grab_object( ptr->obj );
}
}
return NULL; return NULL;
} }
/* allocate a namespace */
struct namespace *create_namespace( unsigned int hash_size, int case_sensitive )
{
struct namespace *namespace;
unsigned int i;
namespace = mem_alloc( sizeof(*namespace) + (hash_size - 1) * sizeof(namespace->names[0]) );
if (namespace)
{
namespace->hash_size = hash_size;
namespace->case_sensitive = case_sensitive;
for (i = 0; i < hash_size; i++) list_init( &namespace->names[i] );
}
return namespace;
}
/* functions for unimplemented/default object operations */ /* functions for unimplemented/default object operations */
int no_add_queue( struct object *obj, struct wait_queue_entry *entry ) int no_add_queue( struct object *obj, struct wait_queue_entry *entry )
......
...@@ -24,11 +24,13 @@ ...@@ -24,11 +24,13 @@
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/time.h> #include <sys/time.h>
#include "wine/server_protocol.h" #include "wine/server_protocol.h"
#include "list.h"
#define DEBUG_OBJECTS #define DEBUG_OBJECTS
/* kernel objects */ /* kernel objects */
struct namespace;
struct object; struct object;
struct object_name; struct object_name;
struct thread; struct thread;
...@@ -79,8 +81,7 @@ struct object ...@@ -79,8 +81,7 @@ struct object
struct wait_queue_entry *tail; struct wait_queue_entry *tail;
struct object_name *name; struct object_name *name;
#ifdef DEBUG_OBJECTS #ifdef DEBUG_OBJECTS
struct object *prev; struct list obj_list;
struct object *next;
#endif #endif
}; };
...@@ -96,12 +97,14 @@ extern void *mem_alloc( size_t size ); /* malloc wrapper */ ...@@ -96,12 +97,14 @@ extern void *mem_alloc( size_t size ); /* malloc wrapper */
extern void *memdup( const void *data, size_t len ); extern void *memdup( const void *data, size_t len );
extern void *alloc_object( const struct object_ops *ops, int fd ); extern void *alloc_object( const struct object_ops *ops, int fd );
extern void dump_object_name( struct object *obj ); extern void dump_object_name( struct object *obj );
extern void *create_named_object( const struct object_ops *ops, const WCHAR *name, size_t len ); extern void *create_named_object( struct namespace *namespace, const struct object_ops *ops,
const WCHAR *name, size_t len );
extern struct namespace *create_namespace( unsigned int hash_size, int case_sensitive );
/* grab/release_object can take any pointer, but you better make sure */ /* grab/release_object can take any pointer, but you better make sure */
/* that the thing pointed to starts with a struct object... */ /* that the thing pointed to starts with a struct object... */
extern struct object *grab_object( void *obj ); extern struct object *grab_object( void *obj );
extern void release_object( void *obj ); extern void release_object( void *obj );
extern struct object *find_object( const WCHAR *name, size_t len ); extern struct object *find_object( const struct namespace *namespace, const WCHAR *name, size_t len );
extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern int no_satisfied( struct object *obj, struct thread *thread ); extern int no_satisfied( struct object *obj, struct thread *thread );
extern int no_get_fd( struct object *obj ); extern int no_get_fd( struct object *obj );
...@@ -209,4 +212,7 @@ extern const char *server_argv0; ...@@ -209,4 +212,7 @@ extern const char *server_argv0;
/* server start time used for GetTickCount() */ /* server start time used for GetTickCount() */
extern unsigned int server_start_ticks; extern unsigned int server_start_ticks;
/* name space for synchronization objects */
extern struct namespace *sync_namespace;
#endif /* __WINE_SERVER_OBJECT_H */ #endif /* __WINE_SERVER_OBJECT_H */
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
struct msg_queue; struct msg_queue;
struct atom_table; struct atom_table;
struct handle_table;
struct startup_info; struct startup_info;
/* process startup state */ /* process startup state */
...@@ -54,7 +55,7 @@ struct process ...@@ -54,7 +55,7 @@ struct process
struct process *parent; /* parent process */ struct process *parent; /* parent process */
struct thread *thread_list; /* head of the thread list */ struct thread *thread_list; /* head of the thread list */
struct thread *debugger; /* thread debugging this process */ struct thread *debugger; /* thread debugging this process */
struct object *handles; /* handle entries */ struct handle_table *handles; /* handle entries */
int exit_code; /* process exit code */ int exit_code; /* process exit code */
int running_threads; /* number of threads running in this process */ int running_threads; /* number of threads running in this process */
struct timeval start_time; /* absolute time at process start */ struct timeval start_time; /* absolute time at process start */
......
...@@ -70,7 +70,7 @@ static struct semaphore *create_semaphore( const WCHAR *name, size_t len, ...@@ -70,7 +70,7 @@ static struct semaphore *create_semaphore( const WCHAR *name, size_t len,
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return NULL; return NULL;
} }
if ((sem = create_named_object( &semaphore_ops, name, len ))) if ((sem = create_named_object( sync_namespace, &semaphore_ops, name, len )))
{ {
if (get_error() != STATUS_OBJECT_NAME_COLLISION) if (get_error() != STATUS_OBJECT_NAME_COLLISION)
{ {
...@@ -153,7 +153,7 @@ DECL_HANDLER(create_semaphore) ...@@ -153,7 +153,7 @@ DECL_HANDLER(create_semaphore)
/* open a handle to a semaphore */ /* open a handle to a semaphore */
DECL_HANDLER(open_semaphore) DECL_HANDLER(open_semaphore)
{ {
reply->handle = open_object( get_req_data(), get_req_data_size(), reply->handle = open_object( sync_namespace, get_req_data(), get_req_data_size(),
&semaphore_ops, req->access, req->inherit ); &semaphore_ops, req->access, req->inherit );
} }
......
...@@ -72,7 +72,7 @@ static struct timer *create_timer( const WCHAR *name, size_t len, int manual ) ...@@ -72,7 +72,7 @@ static struct timer *create_timer( const WCHAR *name, size_t len, int manual )
{ {
struct timer *timer; struct timer *timer;
if ((timer = create_named_object( &timer_ops, name, len ))) if ((timer = create_named_object( sync_namespace, &timer_ops, name, len )))
{ {
if (get_error() != STATUS_OBJECT_NAME_COLLISION) if (get_error() != STATUS_OBJECT_NAME_COLLISION)
{ {
...@@ -211,7 +211,7 @@ DECL_HANDLER(create_timer) ...@@ -211,7 +211,7 @@ DECL_HANDLER(create_timer)
/* open a handle to a timer */ /* open a handle to a timer */
DECL_HANDLER(open_timer) DECL_HANDLER(open_timer)
{ {
reply->handle = open_object( get_req_data(), get_req_data_size(), reply->handle = open_object( sync_namespace, get_req_data(), get_req_data_size(),
&timer_ops, req->access, req->inherit ); &timer_ops, req->access, req->inherit );
} }
......
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