Release 980927
[wine.git] / server / object.c
blob82f118211a65a9705fc85e920f1672f6cf106492
1 /*
2 * Server-side objects
3 * These are the server equivalent of K32OBJ
5 * Copyright (C) 1998 Alexandre Julliard
6 */
8 #include <assert.h>
9 #include <limits.h>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "winerror.h"
14 #include "server.h"
15 #include "server/thread.h"
17 int debug_level = 0;
19 struct object_name
21 struct object_name *next;
22 struct object *obj;
23 int len;
24 char name[1];
27 #define NAME_HASH_SIZE 37
29 static struct object_name *names[NAME_HASH_SIZE];
31 /*****************************************************************/
33 void *mem_alloc( size_t size )
35 void *ptr = malloc( size );
36 if (ptr) memset( ptr, 0x55, size );
37 else if (current) SET_ERROR( ERROR_OUTOFMEMORY );
38 return ptr;
41 /*****************************************************************/
43 static int get_name_hash( const char *name )
45 int hash = 0;
46 while (*name) hash ^= *name++;
47 return hash % NAME_HASH_SIZE;
50 static struct object_name *add_name( struct object *obj, const char *name )
52 struct object_name *ptr;
53 int hash = get_name_hash( name );
54 int len = strlen( name );
56 if (!(ptr = (struct object_name *)mem_alloc( sizeof(*ptr) + len )))
57 return NULL;
58 ptr->next = names[hash];
59 ptr->obj = obj;
60 ptr->len = len;
61 strcpy( ptr->name, name );
62 names[hash] = ptr;
63 return ptr;
66 static void free_name( struct object *obj )
68 int hash = get_name_hash( obj->name->name );
69 struct object_name **pptr = &names[hash];
70 while (*pptr && *pptr != obj->name) pptr = &(*pptr)->next;
71 assert( *pptr );
72 *pptr = (*pptr)->next;
73 free( obj->name );
76 /* initialize an already allocated object */
77 /* return 1 if OK, 0 on error */
78 int init_object( struct object *obj, const struct object_ops *ops,
79 const char *name )
81 obj->refcount = 1;
82 obj->ops = ops;
83 obj->head = NULL;
84 obj->tail = NULL;
85 if (!name) obj->name = NULL;
86 else if (!(obj->name = add_name( obj, name ))) return 0;
87 return 1;
90 struct object *create_named_object( const char *name, const struct object_ops *ops, size_t size )
92 struct object *obj;
93 if ((obj = find_object( name )))
95 if (obj->ops == ops)
97 SET_ERROR( ERROR_ALREADY_EXISTS );
98 return obj;
100 SET_ERROR( ERROR_INVALID_HANDLE );
101 return NULL;
103 if (!(obj = mem_alloc( size ))) return NULL;
104 if (!init_object( obj, ops, name ))
106 free( obj );
107 return NULL;
109 CLEAR_ERROR();
110 return obj;
113 /* grab an object (i.e. increment its refcount) and return the object */
114 struct object *grab_object( void *ptr )
116 struct object *obj = (struct object *)ptr;
117 assert( obj->refcount < INT_MAX );
118 obj->refcount++;
119 return obj;
122 /* release an object (i.e. decrement its refcount) */
123 void release_object( void *ptr )
125 struct object *obj = (struct object *)ptr;
126 assert( obj->refcount );
127 if (!--obj->refcount)
129 /* if the refcount is 0, nobody can be in the wait queue */
130 assert( !obj->head );
131 assert( !obj->tail );
132 if (obj->name) free_name( obj );
133 obj->ops->destroy( obj );
137 /* find an object by its name; the refcount is incremented */
138 struct object *find_object( const char *name )
140 struct object_name *ptr;
141 if (!name) return NULL;
142 ptr = names[ get_name_hash( name ) ];
143 while (ptr && strcmp( ptr->name, name )) ptr = ptr->next;
144 if (!ptr) return NULL;
145 return grab_object( ptr->obj );