Added support for adding and removing pages dynamically from a
[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 #include "server/process.h"
14 #include "server/thread.h"
15
16 struct event
17 {
18     struct object  obj;             /* object header */
19     int            manual_reset;    /* is it a manual reset event? */
20     int            signaled;        /* event has been signaled */
21 };
22
23 static void event_dump( struct object *obj, int verbose );
24 static int event_signaled( struct object *obj, struct thread *thread );
25 static int event_satisfied( struct object *obj, struct thread *thread );
26 static void event_destroy( struct object *obj );
27
28 static const struct object_ops event_ops =
29 {
30     event_dump,
31     add_queue,
32     remove_queue,
33     event_signaled,
34     event_satisfied,
35     no_read_fd,
36     no_write_fd,
37     no_flush,
38     no_get_file_info,
39     event_destroy
40 };
41
42
43 struct object *create_event( const char *name, int manual_reset, int initial_state )
44 {
45     struct event *event;
46
47     if (!(event = (struct event *)create_named_object( name, &event_ops, sizeof(*event) )))
48         return NULL;
49     if (GET_ERROR() != ERROR_ALREADY_EXISTS)
50     {
51         /* initialize it if it didn't already exist */
52         event->manual_reset = manual_reset;
53         event->signaled     = initial_state;
54     }
55     return &event->obj;
56 }
57
58 int open_event( unsigned int access, int inherit, const char *name )
59 {
60     return open_object( name, &event_ops, access, inherit );
61 }
62
63 int pulse_event( int handle )
64 {
65     struct event *event;
66
67     if (!(event = (struct event *)get_handle_obj( current->process, handle,
68                                                   EVENT_MODIFY_STATE, &event_ops )))
69         return 0;
70     event->signaled = 1;
71     /* wake up all waiters if manual reset, a single one otherwise */
72     wake_up( &event->obj, !event->manual_reset );
73     event->signaled = 0;
74     release_object( event );
75     return 1;
76 }
77
78 int set_event( int handle )
79 {
80     struct event *event;
81
82     if (!(event = (struct event *)get_handle_obj( current->process, handle,
83                                                   EVENT_MODIFY_STATE, &event_ops )))
84         return 0;
85     event->signaled = 1;
86     /* wake up all waiters if manual reset, a single one otherwise */
87     wake_up( &event->obj, !event->manual_reset );
88     release_object( event );
89     return 1;
90 }
91
92 int reset_event( int handle )
93 {
94     struct event *event;
95
96     if (!(event = (struct event *)get_handle_obj( current->process, handle,
97                                                   EVENT_MODIFY_STATE, &event_ops )))
98         return 0;
99     event->signaled = 0;
100     release_object( event );
101     return 1;
102 }
103
104 static void event_dump( struct object *obj, int verbose )
105 {
106     struct event *event = (struct event *)obj;
107     assert( obj->ops == &event_ops );
108     fprintf( stderr, "Event manual=%d signaled=%d name='%s'\n",
109              event->manual_reset, event->signaled,
110              get_object_name( &event->obj ) );
111 }
112
113 static int event_signaled( struct object *obj, struct thread *thread )
114 {
115     struct event *event = (struct event *)obj;
116     assert( obj->ops == &event_ops );
117     return event->signaled;
118 }
119
120 static int event_satisfied( struct object *obj, struct thread *thread )
121 {
122     struct event *event = (struct event *)obj;
123     assert( obj->ops == &event_ops );
124     /* Reset if it's an auto-reset event */
125     if (!event->manual_reset) event->signaled = 0;
126     return 0;  /* Not abandoned */
127 }
128
129 static void event_destroy( struct object *obj )
130 {
131     struct event *event = (struct event *)obj;
132     assert( obj->ops == &event_ops );
133     free( event );
134 }