3 * These are the server equivalent of K32OBJ
5 * Copyright (C) 1998 Alexandre Julliard
21 struct object_name
*next
;
27 #define NAME_HASH_SIZE 37
29 static struct object_name
*names
[NAME_HASH_SIZE
];
32 static struct object
*first
;
34 void dump_objects(void)
36 struct object
*ptr
= first
;
39 fprintf( stderr
, "%p:%d: ", ptr
, ptr
->refcount
);
40 ptr
->ops
->dump( ptr
, 1 );
46 /*****************************************************************/
48 void *mem_alloc( size_t size
)
50 void *ptr
= malloc( size
);
51 if (ptr
) memset( ptr
, 0x55, size
);
52 else if (current
) SET_ERROR( ERROR_OUTOFMEMORY
);
56 /*****************************************************************/
58 static int get_name_hash( const char *name
)
61 while (*name
) hash
^= *name
++;
62 return hash
% NAME_HASH_SIZE
;
65 static struct object_name
*add_name( struct object
*obj
, const char *name
)
67 struct object_name
*ptr
;
68 int hash
= get_name_hash( name
);
69 int len
= strlen( name
);
71 if (!(ptr
= (struct object_name
*)mem_alloc( sizeof(*ptr
) + len
)))
73 ptr
->next
= names
[hash
];
76 strcpy( ptr
->name
, name
);
81 static void free_name( struct object
*obj
)
83 int hash
= get_name_hash( obj
->name
->name
);
84 struct object_name
**pptr
= &names
[hash
];
85 while (*pptr
&& *pptr
!= obj
->name
) pptr
= &(*pptr
)->next
;
87 *pptr
= (*pptr
)->next
;
91 /* initialize an already allocated object */
92 /* return 1 if OK, 0 on error */
93 int init_object( struct object
*obj
, const struct object_ops
*ops
,
100 if (!name
) obj
->name
= NULL
;
101 else if (!(obj
->name
= add_name( obj
, name
))) return 0;
104 if ((obj
->next
= first
) != NULL
) obj
->next
->prev
= obj
;
110 /* allocate and initialize an object */
111 void *alloc_object( size_t size
, const struct object_ops
*ops
, const char *name
)
113 struct object
*obj
= mem_alloc( size
);
114 if (obj
) init_object( obj
, ops
, name
);
118 struct object
*create_named_object( const char *name
, const struct object_ops
*ops
, size_t size
)
121 if ((obj
= find_object( name
)))
125 SET_ERROR( ERROR_ALREADY_EXISTS
);
128 SET_ERROR( ERROR_INVALID_HANDLE
);
131 if (!(obj
= mem_alloc( size
))) return NULL
;
132 if (!init_object( obj
, ops
, name
))
141 /* return a pointer to the object name, or to an empty string */
142 const char *get_object_name( struct object
*obj
)
144 if (!obj
->name
) return "";
145 return obj
->name
->name
;
148 /* grab an object (i.e. increment its refcount) and return the object */
149 struct object
*grab_object( void *ptr
)
151 struct object
*obj
= (struct object
*)ptr
;
152 assert( obj
->refcount
< INT_MAX
);
157 /* release an object (i.e. decrement its refcount) */
158 void release_object( void *ptr
)
160 struct object
*obj
= (struct object
*)ptr
;
161 assert( obj
->refcount
);
162 if (!--obj
->refcount
)
164 /* if the refcount is 0, nobody can be in the wait queue */
165 assert( !obj
->head
);
166 assert( !obj
->tail
);
167 if (obj
->name
) free_name( obj
);
169 if (obj
->next
) obj
->next
->prev
= obj
->prev
;
170 if (obj
->prev
) obj
->prev
->next
= obj
->next
;
171 else first
= obj
->next
;
173 obj
->ops
->destroy( obj
);
177 /* find an object by its name; the refcount is incremented */
178 struct object
*find_object( const char *name
)
180 struct object_name
*ptr
;
181 if (!name
) return NULL
;
182 ptr
= names
[ get_name_hash( name
) ];
183 while (ptr
&& strcmp( ptr
->name
, name
)) ptr
= ptr
->next
;
184 if (!ptr
) return NULL
;
185 return grab_object( ptr
->obj
);
188 /* functions for unimplemented object operations */
190 int no_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
192 SET_ERROR( ERROR_INVALID_HANDLE
);
196 int no_satisfied( struct object
*obj
, struct thread
*thread
)
198 return 0; /* not abandoned */
201 int no_read_fd( struct object
*obj
)
203 SET_ERROR( ERROR_INVALID_HANDLE
);
207 int no_write_fd( struct object
*obj
)
209 SET_ERROR( ERROR_INVALID_HANDLE
);
213 int no_flush( struct object
*obj
)
215 SET_ERROR( ERROR_INVALID_HANDLE
);
219 int no_get_file_info( struct object
*obj
, struct get_file_info_reply
*info
)
221 SET_ERROR( ERROR_INVALID_HANDLE
);
225 void default_select_event( int event
, void *private )
227 struct object
*obj
= (struct object
*)private;