Various registry-related PostScript driver enhancements.
[wine] / server / queue.c
1 /*
2  * Server-side message queues
3  *
4  * Copyright (C) 2000 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 #include "handle.h"
12 #include "thread.h"
13 #include "process.h"
14 #include "request.h"
15
16 struct msg_queue
17 {
18     struct object  obj;             /* object header */
19     struct thread *thread;          /* thread owning this queue */
20     int            signaled;        /* queue has been signaled */
21 };
22
23 static void msg_queue_dump( struct object *obj, int verbose );
24 static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry );
25 static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
26 static int msg_queue_signaled( struct object *obj, struct thread *thread );
27 static int msg_queue_satisfied( struct object *obj, struct thread *thread );
28
29 static const struct object_ops msg_queue_ops =
30 {
31     sizeof(struct msg_queue),  /* size */
32     msg_queue_dump,            /* dump */
33     msg_queue_add_queue,       /* add_queue */
34     msg_queue_remove_queue,    /* remove_queue */
35     msg_queue_signaled,        /* signaled */
36     msg_queue_satisfied,       /* satisfied */
37     NULL,                      /* get_poll_events */
38     NULL,                      /* poll_event */
39     no_get_fd,                 /* get_fd */
40     no_flush,                  /* flush */
41     no_get_file_info,          /* get_file_info */
42     no_destroy                 /* destroy */
43 };
44
45
46 static struct msg_queue *create_msg_queue( struct thread *thread )
47 {
48     struct msg_queue *queue;
49
50     if ((queue = alloc_object( &msg_queue_ops, -1 )))
51     {
52         queue->signaled = 0;
53         queue->thread = thread;
54         thread->queue = queue;
55         if (!thread->process->queue)
56             thread->process->queue = (struct msg_queue *)grab_object( queue );
57     }
58     return queue;
59 }
60
61 static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry )
62 {
63     struct msg_queue *queue = (struct msg_queue *)obj;
64     struct process *process = entry->thread->process;
65
66     /* if waiting on the main process queue, set the idle event */
67     if (entry->thread == queue->thread && process->queue == queue)
68     {
69         if (process->idle_event) set_event( process->idle_event );
70     }
71     add_queue( obj, entry );
72     return 1;
73 }
74
75 static void msg_queue_remove_queue(struct object *obj, struct wait_queue_entry *entry )
76 {
77     struct msg_queue *queue = (struct msg_queue *)obj;
78     struct process *process = entry->thread->process;
79
80     remove_queue( obj, entry );
81
82     /* if waiting on the main process queue, reset the idle event */
83     if (entry->thread == queue->thread && process->queue == queue)
84     {
85         if (process->idle_event) reset_event( process->idle_event );
86     }
87 }
88
89 static void msg_queue_dump( struct object *obj, int verbose )
90 {
91     struct msg_queue *queue = (struct msg_queue *)obj;
92     fprintf( stderr, "Msg queue signaled=%d owner=%p\n", queue->signaled, queue->thread );
93 }
94
95 static int msg_queue_signaled( struct object *obj, struct thread *thread )
96 {
97     struct msg_queue *queue = (struct msg_queue *)obj;
98     return queue->signaled;
99 }
100
101 static int msg_queue_satisfied( struct object *obj, struct thread *thread )
102 {
103     struct msg_queue *queue = (struct msg_queue *)obj;
104     queue->signaled = 0;
105     return 0;  /* Not abandoned */
106 }
107
108 /* get the message queue of the current thread */
109 DECL_HANDLER(get_msg_queue)
110 {
111     struct msg_queue *queue = current->queue;
112
113     req->handle = 0;
114     if (!queue) queue = create_msg_queue( current );
115     if (queue) req->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 );
116 }
117
118 /* wake up a message queue */
119 DECL_HANDLER(wake_queue)
120 {
121     struct msg_queue *queue = (struct msg_queue *)get_handle_obj( current->process, req->handle,
122                                                                   0, &msg_queue_ops );
123     if (queue)
124     {
125         queue->signaled = 1;
126         wake_up( &queue->obj, 0 );
127         release_object( queue );
128     }
129 }