3 * These are the server equivalent of K32OBJ
5 * Copyright (C) 1998 Alexandre Julliard
15 #include "server/thread.h"
21 struct object_name
*next
;
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
);
41 /*****************************************************************/
43 static int get_name_hash( const char *name
)
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
)))
58 ptr
->next
= names
[hash
];
61 strcpy( ptr
->name
, name
);
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
;
72 *pptr
= (*pptr
)->next
;
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
,
85 if (!name
) obj
->name
= NULL
;
86 else if (!(obj
->name
= add_name( obj
, name
))) return 0;
90 struct object
*create_named_object( const char *name
, const struct object_ops
*ops
, size_t size
)
93 if ((obj
= find_object( name
)))
97 SET_ERROR( ERROR_ALREADY_EXISTS
);
100 SET_ERROR( ERROR_INVALID_HANDLE
);
103 if (!(obj
= mem_alloc( size
))) return NULL
;
104 if (!init_object( obj
, ops
, name
))
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
);
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
);