Added DebugBreak.
[wine] / server / event.c
1 /*
2  * Server-side event management
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 #include "winerror.h"
12 #include "winnt.h"
13
14 #include "handle.h"
15 #include "thread.h"
16
17 struct event
18 {
19     struct object  obj;             /* object header */
20     int            manual_reset;    /* is it a manual reset event? */
21     int            signaled;        /* event has been signaled */
22 };
23
24 static void event_dump( struct object *obj, int verbose );
25 static int event_signaled( struct object *obj, struct thread *thread );
26 static int event_satisfied( struct object *obj, struct thread *thread );
27 static void event_destroy( struct object *obj );
28
29 static const struct object_ops event_ops =
30 {
31     event_dump,
32     add_queue,
33     remove_queue,
34     event_signaled,
35     event_satisfied,
36     no_read_fd,
37     no_write_fd,
38     no_flush,
39     no_get_file_info,
40     event_destroy
41 };
42
43
44 static struct object *create_event( const char *name, int manual_reset, int initial_state )
45 {
46     struct event *event;
47
48     if (!(event = (struct event *)create_named_object( name, &event_ops, sizeof(*event) )))
49         return NULL;
50     if (GET_ERROR() != ERROR_ALREADY_EXISTS)
51     {
52         /* initialize it if it didn't already exist */
53         event->manual_reset = manual_reset;
54         event->signaled     = initial_state;
55     }
56     return &event->obj;
57 }
58
59 static int pulse_event( int handle )
60 {
61     struct event *event;
62
63     if (!(event = (struct event *)get_handle_obj( current->process, handle,
64                                                   EVENT_MODIFY_STATE, &event_ops )))
65         return 0;
66     event->signaled = 1;
67     /* wake up all waiters if manual reset, a single one otherwise */
68     wake_up( &event->obj, !event->manual_reset );
69     event->signaled = 0;
70     release_object( event );
71     return 1;
72 }
73
74 static int set_event( int handle )
75 {
76     struct event *event;
77
78     if (!(event = (struct event *)get_handle_obj( current->process, handle,
79                                                   EVENT_MODIFY_STATE, &event_ops )))
80         return 0;
81     event->signaled = 1;
82     /* wake up all waiters if manual reset, a single one otherwise */
83     wake_up( &event->obj, !event->manual_reset );
84     release_object( event );
85     return 1;
86 }
87
88 static int reset_event( int handle )
89 {
90     struct event *event;
91
92     if (!(event = (struct event *)get_handle_obj( current->process, handle,
93                                                   EVENT_MODIFY_STATE, &event_ops )))
94         return 0;
95     event->signaled = 0;
96     release_object( event );
97     return 1;
98 }
99
100 static void event_dump( struct object *obj, int verbose )
101 {
102     struct event *event = (struct event *)obj;
103     assert( obj->ops == &event_ops );
104     fprintf( stderr, "Event manual=%d signaled=%d name='%s'\n",
105              event->manual_reset, event->signaled,
106              get_object_name( &event->obj ) );
107 }
108
109 static int event_signaled( struct object *obj, struct thread *thread )
110 {
111     struct event *event = (struct event *)obj;
112     assert( obj->ops == &event_ops );
113     return event->signaled;
114 }
115
116 static int event_satisfied( struct object *obj, struct thread *thread )
117 {
118     struct event *event = (struct event *)obj;
119     assert( obj->ops == &event_ops );
120     /* Reset if it's an auto-reset event */
121     if (!event->manual_reset) event->signaled = 0;
122     return 0;  /* Not abandoned */
123 }
124
125 static void event_destroy( struct object *obj )
126 {
127     struct event *event = (struct event *)obj;
128     assert( obj->ops == &event_ops );
129     free( event );
130 }
131
132 /* create an event */
133 DECL_HANDLER(create_event)
134 {
135     struct create_event_reply reply = { -1 };
136     struct object *obj;
137     char *name = (char *)data;
138     if (!len) name = NULL;
139     else CHECK_STRING( "create_event", name, len );
140
141     obj = create_event( name, req->manual_reset, req->initial_state );
142     if (obj)
143     {
144         reply.handle = alloc_handle( current->process, obj, EVENT_ALL_ACCESS, req->inherit );
145         release_object( obj );
146     }
147     send_reply( current, -1, 1, &reply, sizeof(reply) );
148 }
149
150 /* open a handle to an event */
151 DECL_HANDLER(open_event)
152 {
153     struct open_event_reply reply;
154     char *name = (char *)data;
155     if (!len) name = NULL;
156     else CHECK_STRING( "open_event", name, len );
157
158     reply.handle = open_object( name, &event_ops, req->access, req->inherit );
159     send_reply( current, -1, 1, &reply, sizeof(reply) );
160 }
161
162 /* do an event operation */
163 DECL_HANDLER(event_op)
164 {
165     switch(req->op)
166     {
167     case PULSE_EVENT:
168         pulse_event( req->handle );
169         break;
170     case SET_EVENT:
171         set_event( req->handle );
172         break;
173     case RESET_EVENT:
174         reset_event( req->handle );
175         break;
176     default:
177         fatal_protocol_error( "event_op: invalid operation %d\n", req->op );
178     }
179     send_reply( current, -1, 0 );
180 }