11 struct pa_mainloop_api
* mainloop
;
13 void (*callback
)(struct iochannel
*io
, void *userdata
);
21 void* input_source
, *output_source
;
24 static void enable_mainloop_sources(struct iochannel
*io
) {
27 if (io
->input_source
== io
->output_source
) {
28 enum pa_mainloop_api_io_events e
= PA_MAINLOOP_API_IO_EVENT_NULL
;
29 assert(io
->input_source
);
32 e
|= PA_MAINLOOP_API_IO_EVENT_INPUT
;
34 e
|= PA_MAINLOOP_API_IO_EVENT_OUTPUT
;
36 io
->mainloop
->enable_io(io
->mainloop
, io
->input_source
, e
);
39 io
->mainloop
->enable_io(io
->mainloop
, io
->input_source
, io
->readable
? PA_MAINLOOP_API_IO_EVENT_NULL
: PA_MAINLOOP_API_IO_EVENT_INPUT
);
40 if (io
->output_source
)
41 io
->mainloop
->enable_io(io
->mainloop
, io
->output_source
, io
->writable
? PA_MAINLOOP_API_IO_EVENT_NULL
: PA_MAINLOOP_API_IO_EVENT_OUTPUT
);
45 static void callback(struct pa_mainloop_api
* m
, void *id
, int fd
, enum pa_mainloop_api_io_events events
, void *userdata
) {
46 struct iochannel
*io
= userdata
;
48 assert(m
&& fd
>= 0 && events
&& userdata
);
50 if ((events
& PA_MAINLOOP_API_IO_EVENT_INPUT
) && !io
->readable
) {
53 assert(id
== io
->input_source
);
56 if ((events
& PA_MAINLOOP_API_IO_EVENT_OUTPUT
) && !io
->writable
) {
59 assert(id
== io
->output_source
);
63 enable_mainloop_sources(io
);
66 io
->callback(io
, io
->userdata
);
70 struct iochannel
* iochannel_new(struct pa_mainloop_api
*m
, int ifd
, int ofd
) {
72 assert(m
&& (ifd
>= 0 || ofd
>= 0));
74 io
= malloc(sizeof(struct iochannel
));
87 make_nonblock_fd(io
->ifd
);
88 io
->input_source
= io
->output_source
= m
->source_io(m
, ifd
, PA_MAINLOOP_API_IO_EVENT_BOTH
, callback
, io
);
92 make_nonblock_fd(io
->ifd
);
93 io
->input_source
= m
->source_io(m
, ifd
, PA_MAINLOOP_API_IO_EVENT_INPUT
, callback
, io
);
95 io
->input_source
= NULL
;
98 make_nonblock_fd(io
->ofd
);
99 io
->output_source
= m
->source_io(m
, ofd
, PA_MAINLOOP_API_IO_EVENT_OUTPUT
, callback
, io
);
101 io
->output_source
= NULL
;
107 void iochannel_free(struct iochannel
*io
) {
113 if (io
->ofd
>= 0 && io
->ofd
!= io
->ifd
)
117 if (io
->input_source
)
118 io
->mainloop
->cancel_io(io
->mainloop
, io
->input_source
);
119 if (io
->output_source
&& (io
->output_source
!= io
->input_source
))
120 io
->mainloop
->cancel_io(io
->mainloop
, io
->output_source
);
125 int iochannel_is_readable(struct iochannel
*io
) {
130 int iochannel_is_writable(struct iochannel
*io
) {
135 ssize_t
iochannel_write(struct iochannel
*io
, const void*data
, size_t l
) {
137 assert(io
&& data
&& l
&& io
->ofd
>= 0);
139 if ((r
= write(io
->ofd
, data
, l
)) >= 0) {
141 enable_mainloop_sources(io
);
147 ssize_t
iochannel_read(struct iochannel
*io
, void*data
, size_t l
) {
150 assert(io
&& data
&& l
&& io
->ifd
>= 0);
152 if ((r
= read(io
->ifd
, data
, l
)) >= 0) {
154 enable_mainloop_sources(io
);
160 void iochannel_set_callback(struct iochannel
*io
, void (*callback
)(struct iochannel
*io
, void *userdata
), void *userdata
) {
162 io
->callback
= callback
;
163 io
->userdata
= userdata
;
166 void iochannel_set_noclose(struct iochannel
*io
, int b
) {
171 void iochannel_peer_to_string(struct iochannel
*io
, char*s
, size_t l
) {
172 assert(io
&& s
&& l
);
173 peer_to_string(s
, l
, io
->ifd
);