event.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Server-side event management
  3. *
  4. * Copyright (C) 1998 Alexandre Julliard
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include "config.h"
  21. #include "wine/port.h"
  22. #include <assert.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include "windef.h"
  26. #include "handle.h"
  27. #include "thread.h"
  28. #include "request.h"
  29. struct event
  30. {
  31. struct object obj; /* object header */
  32. int manual_reset; /* is it a manual reset event? */
  33. int signaled; /* event has been signaled */
  34. };
  35. static void event_dump( struct object *obj, int verbose );
  36. static int event_signaled( struct object *obj, struct thread *thread );
  37. static int event_satisfied( struct object *obj, struct thread *thread );
  38. static const struct object_ops event_ops =
  39. {
  40. sizeof(struct event), /* size */
  41. event_dump, /* dump */
  42. add_queue, /* add_queue */
  43. remove_queue, /* remove_queue */
  44. event_signaled, /* signaled */
  45. event_satisfied, /* satisfied */
  46. no_get_fd, /* get_fd */
  47. no_destroy /* destroy */
  48. };
  49. struct event *create_event( const WCHAR *name, size_t len,
  50. int manual_reset, int initial_state )
  51. {
  52. struct event *event;
  53. if ((event = create_named_object( sync_namespace, &event_ops, name, len )))
  54. {
  55. if (get_error() != STATUS_OBJECT_NAME_COLLISION)
  56. {
  57. /* initialize it if it didn't already exist */
  58. event->manual_reset = manual_reset;
  59. event->signaled = initial_state;
  60. }
  61. }
  62. return event;
  63. }
  64. struct event *get_event_obj( struct process *process, obj_handle_t handle, unsigned int access )
  65. {
  66. return (struct event *)get_handle_obj( process, handle, access, &event_ops );
  67. }
  68. void pulse_event( struct event *event )
  69. {
  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. }
  75. void set_event( struct event *event )
  76. {
  77. event->signaled = 1;
  78. /* wake up all waiters if manual reset, a single one otherwise */
  79. wake_up( &event->obj, !event->manual_reset );
  80. }
  81. void reset_event( struct event *event )
  82. {
  83. event->signaled = 0;
  84. }
  85. static void event_dump( struct object *obj, int verbose )
  86. {
  87. struct event *event = (struct event *)obj;
  88. assert( obj->ops == &event_ops );
  89. fprintf( stderr, "Event manual=%d signaled=%d ",
  90. event->manual_reset, event->signaled );
  91. dump_object_name( &event->obj );
  92. fputc( '\n', stderr );
  93. }
  94. static int event_signaled( struct object *obj, struct thread *thread )
  95. {
  96. struct event *event = (struct event *)obj;
  97. assert( obj->ops == &event_ops );
  98. return event->signaled;
  99. }
  100. static int event_satisfied( struct object *obj, struct thread *thread )
  101. {
  102. struct event *event = (struct event *)obj;
  103. assert( obj->ops == &event_ops );
  104. /* Reset if it's an auto-reset event */
  105. if (!event->manual_reset) event->signaled = 0;
  106. return 0; /* Not abandoned */
  107. }
  108. /* create an event */
  109. DECL_HANDLER(create_event)
  110. {
  111. struct event *event;
  112. reply->handle = 0;
  113. if ((event = create_event( get_req_data(), get_req_data_size(),
  114. req->manual_reset, req->initial_state )))
  115. {
  116. reply->handle = alloc_handle( current->process, event, req->access, req->inherit );
  117. release_object( event );
  118. }
  119. }
  120. /* open a handle to an event */
  121. DECL_HANDLER(open_event)
  122. {
  123. reply->handle = open_object( sync_namespace, get_req_data(), get_req_data_size(),
  124. &event_ops, req->access, req->inherit );
  125. }
  126. /* do an event operation */
  127. DECL_HANDLER(event_op)
  128. {
  129. struct event *event;
  130. if (!(event = get_event_obj( current->process, req->handle, EVENT_MODIFY_STATE ))) return;
  131. switch(req->op)
  132. {
  133. case PULSE_EVENT:
  134. pulse_event( event );
  135. break;
  136. case SET_EVENT:
  137. set_event( event );
  138. break;
  139. case RESET_EVENT:
  140. reset_event( event );
  141. break;
  142. default:
  143. fatal_protocol_error( current, "event_op: invalid operation %d\n", req->op );
  144. }
  145. release_object( event );
  146. }