11 struct pa_mainloop_api
* mainloop
;
13 void (*callback
)(struct pa_iochannel
*io
, void *userdata
);
22 void* input_source
, *output_source
;
25 static void enable_mainloop_sources(struct pa_iochannel
*io
) {
28 if (io
->input_source
== io
->output_source
) {
29 enum pa_mainloop_api_io_events e
= PA_MAINLOOP_API_IO_EVENT_NULL
;
30 assert(io
->input_source
);
33 e
|= PA_MAINLOOP_API_IO_EVENT_INPUT
;
35 e
|= PA_MAINLOOP_API_IO_EVENT_OUTPUT
;
37 io
->mainloop
->enable_io(io
->mainloop
, io
->input_source
, e
);
40 io
->mainloop
->enable_io(io
->mainloop
, io
->input_source
, io
->readable
? PA_MAINLOOP_API_IO_EVENT_NULL
: PA_MAINLOOP_API_IO_EVENT_INPUT
);
41 if (io
->output_source
)
42 io
->mainloop
->enable_io(io
->mainloop
, io
->output_source
, io
->writable
? PA_MAINLOOP_API_IO_EVENT_NULL
: PA_MAINLOOP_API_IO_EVENT_OUTPUT
);
46 static void callback(struct pa_mainloop_api
* m
, void *id
, int fd
, enum pa_mainloop_api_io_events events
, void *userdata
) {
47 struct pa_iochannel
*io
= userdata
;
49 assert(m
&& fd
>= 0 && events
&& userdata
);
51 if ((events
& PA_MAINLOOP_API_IO_EVENT_HUP
) && !io
->hungup
) {
56 if ((events
& PA_MAINLOOP_API_IO_EVENT_INPUT
) && !io
->readable
) {
59 assert(id
== io
->input_source
);
62 if ((events
& PA_MAINLOOP_API_IO_EVENT_OUTPUT
) && !io
->writable
) {
65 assert(id
== io
->output_source
);
69 enable_mainloop_sources(io
);
72 io
->callback(io
, io
->userdata
);
76 struct pa_iochannel
* pa_iochannel_new(struct pa_mainloop_api
*m
, int ifd
, int ofd
) {
77 struct pa_iochannel
*io
;
78 assert(m
&& (ifd
>= 0 || ofd
>= 0));
80 io
= malloc(sizeof(struct pa_iochannel
));
94 pa_make_nonblock_fd(io
->ifd
);
95 io
->input_source
= io
->output_source
= m
->source_io(m
, ifd
, PA_MAINLOOP_API_IO_EVENT_BOTH
, callback
, io
);
99 pa_make_nonblock_fd(io
->ifd
);
100 io
->input_source
= m
->source_io(m
, ifd
, PA_MAINLOOP_API_IO_EVENT_INPUT
, callback
, io
);
102 io
->input_source
= NULL
;
105 pa_make_nonblock_fd(io
->ofd
);
106 io
->output_source
= m
->source_io(m
, ofd
, PA_MAINLOOP_API_IO_EVENT_OUTPUT
, callback
, io
);
108 io
->output_source
= NULL
;
114 void pa_iochannel_free(struct pa_iochannel
*io
) {
120 if (io
->ofd
>= 0 && io
->ofd
!= io
->ifd
)
124 if (io
->input_source
)
125 io
->mainloop
->cancel_io(io
->mainloop
, io
->input_source
);
126 if (io
->output_source
&& (io
->output_source
!= io
->input_source
))
127 io
->mainloop
->cancel_io(io
->mainloop
, io
->output_source
);
132 int pa_iochannel_is_readable(struct pa_iochannel
*io
) {
137 int pa_iochannel_is_writable(struct pa_iochannel
*io
) {
142 int pa_iochannel_is_hungup(struct pa_iochannel
*io
) {
147 ssize_t
pa_iochannel_write(struct pa_iochannel
*io
, const void*data
, size_t l
) {
149 assert(io
&& data
&& l
&& io
->ofd
>= 0);
151 if ((r
= write(io
->ofd
, data
, l
)) >= 0) {
153 enable_mainloop_sources(io
);
159 ssize_t
pa_iochannel_read(struct pa_iochannel
*io
, void*data
, size_t l
) {
162 assert(io
&& data
&& io
->ifd
>= 0);
164 if ((r
= read(io
->ifd
, data
, l
)) >= 0) {
166 enable_mainloop_sources(io
);
172 void pa_iochannel_set_callback(struct pa_iochannel
*io
, void (*callback
)(struct pa_iochannel
*io
, void *userdata
), void *userdata
) {
174 io
->callback
= callback
;
175 io
->userdata
= userdata
;
178 void pa_iochannel_set_noclose(struct pa_iochannel
*io
, int b
) {
183 void pa_iochannel_socket_peer_to_string(struct pa_iochannel
*io
, char*s
, size_t l
) {
184 assert(io
&& s
&& l
);
185 pa_peer_to_string(s
, l
, io
->ifd
);
188 int pa_iochannel_socket_set_rcvbuf(struct pa_iochannel
*io
, size_t l
) {
190 return pa_socket_set_rcvbuf(io
->ifd
, l
);
193 int pa_iochannel_socket_set_sndbuf(struct pa_iochannel
*io
, size_t l
) {
195 return pa_socket_set_sndbuf(io
->ofd
, l
);