2 * Server-side semaphore management
4 * Copyright (C) 1998 Alexandre Julliard
19 struct object obj
; /* object header */
20 unsigned int count
; /* current count */
21 unsigned int max
; /* maximum possible count */
24 static void semaphore_dump( struct object
*obj
, int verbose
);
25 static int semaphore_signaled( struct object
*obj
, struct thread
*thread
);
26 static int semaphore_satisfied( struct object
*obj
, struct thread
*thread
);
27 static void semaphore_destroy( struct object
*obj
);
29 static const struct object_ops semaphore_ops
=
44 static struct object
*create_semaphore( const char *name
, unsigned int initial
, unsigned int max
)
46 struct semaphore
*sem
;
48 if (!max
|| (initial
> max
))
50 SET_ERROR( ERROR_INVALID_PARAMETER
);
53 if (!(sem
= (struct semaphore
*)create_named_object( name
, &semaphore_ops
, sizeof(*sem
) )))
55 if (GET_ERROR() != ERROR_ALREADY_EXISTS
)
57 /* initialize it if it didn't already exist */
64 static int release_semaphore( int handle
, unsigned int count
, unsigned int *prev_count
)
66 struct semaphore
*sem
;
68 if (!(sem
= (struct semaphore
*)get_handle_obj( current
->process
, handle
,
69 SEMAPHORE_MODIFY_STATE
, &semaphore_ops
)))
72 *prev_count
= sem
->count
;
73 if (sem
->count
+ count
< sem
->count
|| sem
->count
+ count
> sem
->max
)
75 SET_ERROR( ERROR_TOO_MANY_POSTS
);
80 /* there cannot be any thread waiting if the count is != 0 */
81 assert( !sem
->obj
.head
);
87 wake_up( &sem
->obj
, count
);
89 release_object( sem
);
93 static void semaphore_dump( struct object
*obj
, int verbose
)
95 struct semaphore
*sem
= (struct semaphore
*)obj
;
96 assert( obj
->ops
== &semaphore_ops
);
97 fprintf( stderr
, "Semaphore count=%d max=%d name='%s'\n",
98 sem
->count
, sem
->max
, get_object_name( &sem
->obj
) );
101 static int semaphore_signaled( struct object
*obj
, struct thread
*thread
)
103 struct semaphore
*sem
= (struct semaphore
*)obj
;
104 assert( obj
->ops
== &semaphore_ops
);
105 return (sem
->count
> 0);
108 static int semaphore_satisfied( struct object
*obj
, struct thread
*thread
)
110 struct semaphore
*sem
= (struct semaphore
*)obj
;
111 assert( obj
->ops
== &semaphore_ops
);
112 assert( sem
->count
);
114 return 0; /* not abandoned */
117 static void semaphore_destroy( struct object
*obj
)
119 struct semaphore
*sem
= (struct semaphore
*)obj
;
120 assert( obj
->ops
== &semaphore_ops
);
124 /* create a semaphore */
125 DECL_HANDLER(create_semaphore
)
127 struct create_semaphore_reply reply
= { -1 };
129 char *name
= (char *)data
;
130 if (!len
) name
= NULL
;
131 else CHECK_STRING( "create_semaphore", name
, len
);
133 obj
= create_semaphore( name
, req
->initial
, req
->max
);
136 reply
.handle
= alloc_handle( current
->process
, obj
, SEMAPHORE_ALL_ACCESS
, req
->inherit
);
137 release_object( obj
);
139 send_reply( current
, -1, 1, &reply
, sizeof(reply
) );
142 /* open a handle to a semaphore */
143 DECL_HANDLER(open_semaphore
)
145 struct open_semaphore_reply reply
;
146 char *name
= (char *)data
;
147 if (!len
) name
= NULL
;
148 else CHECK_STRING( "open_semaphore", name
, len
);
150 reply
.handle
= open_object( name
, &semaphore_ops
, req
->access
, req
->inherit
);
151 send_reply( current
, -1, 1, &reply
, sizeof(reply
) );
154 /* release a semaphore */
155 DECL_HANDLER(release_semaphore
)
157 struct release_semaphore_reply reply
;
158 if (release_semaphore( req
->handle
, req
->count
, &reply
.prev_count
)) CLEAR_ERROR();
159 send_reply( current
, -1, 1, &reply
, sizeof(reply
) );