]>
code.delx.au - pulseaudio/blob - src/iochannel.c
f0c4c4998b7fb1420bfd183b869cf90b9554da67
10 struct mainloop
* mainloop
;
12 void (*callback
)(struct iochannel
*io
, void *userdata
);
20 struct mainloop_source
* input_source
, *output_source
;
23 static void enable_mainloop_sources(struct iochannel
*io
) {
26 if (io
->input_source
== io
->output_source
) {
27 enum mainloop_io_event e
= MAINLOOP_IO_EVENT_NULL
;
28 assert(io
->input_source
);
31 e
|= MAINLOOP_IO_EVENT_IN
;
33 e
|= MAINLOOP_IO_EVENT_OUT
;
35 mainloop_source_io_set_events(io
->input_source
, e
);
38 mainloop_source_io_set_events(io
->input_source
, io
->readable
? MAINLOOP_IO_EVENT_NULL
: MAINLOOP_IO_EVENT_IN
);
39 if (io
->output_source
)
40 mainloop_source_io_set_events(io
->output_source
, io
->writable
? MAINLOOP_IO_EVENT_NULL
: MAINLOOP_IO_EVENT_OUT
);
44 static void callback(struct mainloop_source
*s
, int fd
, enum mainloop_io_event events
, void *userdata
) {
45 struct iochannel
*io
= userdata
;
47 assert(s
&& fd
>= 0 && userdata
);
49 if ((events
& MAINLOOP_IO_EVENT_IN
) && !io
->readable
) {
54 if ((events
& MAINLOOP_IO_EVENT_OUT
) && !io
->writable
) {
60 enable_mainloop_sources(io
);
63 io
->callback(io
, io
->userdata
);
67 static void make_nonblock_fd(int fd
) {
70 if ((v
= fcntl(fd
, F_GETFL
)) >= 0)
71 if (!(v
& O_NONBLOCK
))
72 fcntl(fd
, F_SETFL
, v
|O_NONBLOCK
);
75 struct iochannel
* iochannel_new(struct mainloop
*m
, int ifd
, int ofd
) {
77 assert(m
&& (ifd
>= 0 || ofd
>= 0));
79 io
= malloc(sizeof(struct iochannel
));
92 make_nonblock_fd(io
->ifd
);
93 io
->input_source
= io
->output_source
= mainloop_source_new_io(m
, ifd
, MAINLOOP_IO_EVENT_IN
|MAINLOOP_IO_EVENT_OUT
, callback
, io
);
97 make_nonblock_fd(io
->ifd
);
98 io
->input_source
= mainloop_source_new_io(m
, ifd
, MAINLOOP_IO_EVENT_IN
, callback
, io
);
100 io
->input_source
= NULL
;
103 make_nonblock_fd(io
->ofd
);
104 io
->output_source
= mainloop_source_new_io(m
, ofd
, MAINLOOP_IO_EVENT_OUT
, callback
, io
);
106 io
->output_source
= NULL
;
112 void iochannel_free(struct iochannel
*io
) {
118 if (io
->ofd
>= 0 && io
->ofd
!= io
->ifd
)
122 if (io
->input_source
)
123 mainloop_source_free(io
->input_source
);
124 if (io
->output_source
&& io
->output_source
!= io
->input_source
)
125 mainloop_source_free(io
->output_source
);
130 int iochannel_is_readable(struct iochannel
*io
) {
135 int iochannel_is_writable(struct iochannel
*io
) {
140 ssize_t
iochannel_write(struct iochannel
*io
, const void*data
, size_t l
) {
142 assert(io
&& data
&& l
&& io
->ofd
>= 0);
144 if ((r
= write(io
->ofd
, data
, l
)) >= 0) {
146 enable_mainloop_sources(io
);
152 ssize_t
iochannel_read(struct iochannel
*io
, void*data
, size_t l
) {
155 assert(io
&& data
&& l
&& io
->ifd
>= 0);
157 if ((r
= read(io
->ifd
, data
, l
)) >= 0) {
159 enable_mainloop_sources(io
);
165 void iochannel_set_callback(struct iochannel
*io
, void (*callback
)(struct iochannel
*io
, void *userdata
), void *userdata
) {
167 io
->callback
= callback
;
168 io
->userdata
= userdata
;
171 void iochannel_set_noclose(struct iochannel
*io
, int b
) {