Implemented SendMessageTimeout() functions.
[wine/multimedia.git] / server / pipe.c
blob06260f911b311198001da849398cecbd013e6045
1 /*
2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <fcntl.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <sys/errno.h>
13 #include <sys/stat.h>
14 #include <sys/time.h>
15 #include <sys/types.h>
16 #include <time.h>
17 #include <unistd.h>
19 #include "winerror.h"
20 #include "winbase.h"
21 #include "server/thread.h"
23 enum side { READ_SIDE, WRITE_SIDE };
25 struct pipe
27 struct object obj; /* object header */
28 struct pipe *other; /* the pipe other end */
29 int fd; /* Unix file descriptor */
30 enum side side; /* which side of the pipe is this */
33 static void pipe_dump( struct object *obj, int verbose );
34 static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry );
35 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry );
36 static int pipe_signaled( struct object *obj, struct thread *thread );
37 static int pipe_get_read_fd( struct object *obj );
38 static int pipe_get_write_fd( struct object *obj );
39 static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply );
40 static void pipe_destroy( struct object *obj );
42 static const struct object_ops pipe_ops =
44 pipe_dump,
45 pipe_add_queue,
46 pipe_remove_queue,
47 pipe_signaled,
48 no_satisfied,
49 pipe_get_read_fd,
50 pipe_get_write_fd,
51 no_flush,
52 pipe_get_info,
53 pipe_destroy
56 static const struct select_ops select_ops =
58 default_select_event,
59 NULL /* we never set a timeout on a pipe */
62 int create_pipe( struct object *obj[2] )
64 struct pipe *newpipe[2];
65 int fd[2];
67 if (pipe( fd ) == -1)
69 file_set_error();
70 return 0;
72 if (!(newpipe[0] = mem_alloc( sizeof(struct pipe) )))
74 close( fd[0] );
75 close( fd[1] );
76 return 0;
78 if (!(newpipe[1] = mem_alloc( sizeof(struct pipe) )))
80 close( fd[0] );
81 close( fd[1] );
82 free( newpipe[0] );
83 return 0;
85 init_object( &newpipe[0]->obj, &pipe_ops, NULL );
86 init_object( &newpipe[1]->obj, &pipe_ops, NULL );
87 newpipe[0]->fd = fd[0];
88 newpipe[0]->other = newpipe[1];
89 newpipe[0]->side = READ_SIDE;
90 newpipe[1]->fd = fd[1];
91 newpipe[1]->other = newpipe[0];
92 newpipe[1]->side = WRITE_SIDE;
93 obj[0] = &newpipe[0]->obj;
94 obj[1] = &newpipe[1]->obj;
95 CLEAR_ERROR();
96 return 1;
99 static void pipe_dump( struct object *obj, int verbose )
101 struct pipe *pipe = (struct pipe *)obj;
102 assert( obj->ops == &pipe_ops );
103 fprintf( stderr, "Pipe %s-side fd=%d\n",
104 (pipe->side == READ_SIDE) ? "read" : "write", pipe->fd );
107 static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry )
109 struct pipe *pipe = (struct pipe *)obj;
110 assert( obj->ops == &pipe_ops );
111 if (!obj->head) /* first on the queue */
113 if (!add_select_user( pipe->fd,
114 (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT,
115 &select_ops, pipe ))
117 SET_ERROR( ERROR_OUTOFMEMORY );
118 return 0;
121 add_queue( obj, entry );
122 return 1;
125 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry )
127 struct pipe *pipe = (struct pipe *)grab_object(obj);
128 assert( obj->ops == &pipe_ops );
130 remove_queue( obj, entry );
131 if (!obj->head) /* last on the queue is gone */
132 remove_select_user( pipe->fd );
133 release_object( obj );
136 static int pipe_signaled( struct object *obj, struct thread *thread )
138 struct pipe *pipe = (struct pipe *)obj;
139 struct timeval tv = { 0, 0 };
140 fd_set fds;
142 assert( obj->ops == &pipe_ops );
143 FD_ZERO( &fds );
144 FD_SET( pipe->fd, &fds );
145 if (pipe->side == READ_SIDE)
146 return select( pipe->fd + 1, &fds, NULL, NULL, &tv ) > 0;
147 else
148 return select( pipe->fd + 1, NULL, &fds, NULL, &tv ) > 0;
151 static int pipe_get_read_fd( struct object *obj )
153 struct pipe *pipe = (struct pipe *)obj;
154 assert( obj->ops == &pipe_ops );
156 if (!pipe->other)
158 SET_ERROR( ERROR_BROKEN_PIPE );
159 return -1;
161 if (pipe->side != READ_SIDE) /* FIXME: should not be necessary */
163 SET_ERROR( ERROR_ACCESS_DENIED );
164 return -1;
166 return dup( pipe->fd );
169 static int pipe_get_write_fd( struct object *obj )
171 struct pipe *pipe = (struct pipe *)obj;
172 assert( obj->ops == &pipe_ops );
174 if (!pipe->other)
176 SET_ERROR( ERROR_BROKEN_PIPE );
177 return -1;
179 if (pipe->side != WRITE_SIDE) /* FIXME: should not be necessary */
181 SET_ERROR( ERROR_ACCESS_DENIED );
182 return -1;
184 return dup( pipe->fd );
187 static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply )
189 memset( reply, 0, sizeof(*reply) );
190 reply->type = FILE_TYPE_PIPE;
191 return 1;
194 static void pipe_destroy( struct object *obj )
196 struct pipe *pipe = (struct pipe *)obj;
197 assert( obj->ops == &pipe_ops );
199 if (pipe->other) pipe->other->other = NULL;
200 close( pipe->fd );
201 free( pipe );