Commit 5d85f578 authored by Andrew Cook's avatar Andrew Cook Committed by Alexandre Julliard

server: Track handle count of objects.

parent 8cf9108b
......@@ -77,7 +77,7 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
memset( p, 0, sizeof(*p) );
p->GrantedAccess = reply->access;
p->PointerCount = reply->ref_count;
p->HandleCount = 1; /* at least one */
p->HandleCount = reply->handle_count;
if (used_len) *used_len = sizeof(*p);
}
}
......
......@@ -4690,9 +4690,9 @@ struct get_object_info_reply
struct reply_header __header;
unsigned int access;
unsigned int ref_count;
unsigned int handle_count;
data_size_t total;
/* VARARG(name,unicode_str); */
char __pad_20[4];
};
......@@ -5955,6 +5955,6 @@ union generic_reply
struct set_job_completion_port_reply set_job_completion_port_reply;
};
#define SERVER_PROTOCOL_VERSION 465
#define SERVER_PROTOCOL_VERSION 466
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -97,6 +97,20 @@ static inline obj_handle_t handle_global_to_local( obj_handle_t handle )
return handle ^ HANDLE_OBFUSCATOR;
}
/* grab an object and increment its handle count */
static struct object *grab_object_for_handle( struct object *obj )
{
obj->handle_count++;
return grab_object( obj );
}
/* release an object and decrement its handle count */
static void release_object_from_handle( struct object *obj )
{
assert( obj->handle_count );
obj->handle_count--;
release_object( obj );
}
static void handle_table_dump( struct object *obj, int verbose );
static void handle_table_destroy( struct object *obj );
......@@ -166,7 +180,7 @@ static void handle_table_destroy( struct object *obj )
{
struct object *obj = entry->ptr;
entry->ptr = NULL;
if (obj) release_object( obj );
if (obj) release_object_from_handle( obj );
}
free( table->entries );
}
......@@ -229,7 +243,7 @@ static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned
table->last = i;
found:
table->free = i + 1;
entry->ptr = grab_object( obj );
entry->ptr = grab_object_for_handle( obj );
entry->access = access;
return index_to_handle(i);
}
......@@ -355,7 +369,7 @@ struct handle_table *copy_handle_table( struct process *process, struct process
for (i = 0; i <= table->last; i++, ptr++)
{
if (!ptr->ptr) continue;
if (ptr->access & RESERVED_INHERIT) grab_object( ptr->ptr );
if (ptr->access & RESERVED_INHERIT) grab_object_for_handle( ptr->ptr );
else ptr->ptr = NULL; /* don't inherit this entry */
}
}
......@@ -379,7 +393,7 @@ unsigned int close_handle( struct process *process, obj_handle_t handle )
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->last) shrink_handle_table( table );
release_object( obj );
release_object_from_handle( obj );
return STATUS_SUCCESS;
}
......@@ -630,6 +644,7 @@ DECL_HANDLER(get_object_info)
reply->access = get_handle_access( current->process, req->handle );
reply->ref_count = obj->refcount;
reply->handle_count = obj->handle_count;
if ((name = get_object_full_name( obj, &reply->total )))
set_reply_data_ptr( name, min( reply->total, get_reply_max_size() ));
release_object( obj );
......
......@@ -207,6 +207,7 @@ void *alloc_object( const struct object_ops *ops )
if (obj)
{
obj->refcount = 1;
obj->handle_count = 0;
obj->ops = ops;
obj->name = NULL;
obj->sd = NULL;
......@@ -306,6 +307,7 @@ void release_object( void *ptr )
assert( obj->refcount );
if (!--obj->refcount)
{
assert( !obj->handle_count );
/* if the refcount is 0, nobody can be in the wait queue */
assert( list_empty( &obj->wait_queue ));
obj->ops->destroy( obj );
......
......@@ -95,6 +95,7 @@ struct object_ops
struct object
{
unsigned int refcount; /* reference count */
unsigned int handle_count;/* handle count */
const struct object_ops *ops;
struct list wait_queue;
struct object_name *name;
......
......@@ -3269,6 +3269,7 @@ enum coords_relative
@REPLY
unsigned int access; /* granted access mask */
unsigned int ref_count; /* object ref count */
unsigned int handle_count; /* object handle count */
data_size_t total; /* total needed size for name */
VARARG(name,unicode_str); /* object name */
@END
......
......@@ -2088,7 +2088,8 @@ C_ASSERT( FIELD_OFFSET(struct get_object_info_request, handle) == 12 );
C_ASSERT( sizeof(struct get_object_info_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, access) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, ref_count) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, total) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, handle_count) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, total) == 20 );
C_ASSERT( sizeof(struct get_object_info_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct unlink_object_request, handle) == 12 );
C_ASSERT( sizeof(struct unlink_object_request) == 16 );
......
......@@ -3842,6 +3842,7 @@ static void dump_get_object_info_reply( const struct get_object_info_reply *req
{
fprintf( stderr, " access=%08x", req->access );
fprintf( stderr, ", ref_count=%08x", req->ref_count );
fprintf( stderr, ", handle_count=%08x", req->handle_count );
fprintf( stderr, ", total=%u", req->total );
dump_varargs_unicode_str( ", name=", cur_size );
}
......
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