]> code.delx.au - pulseaudio/blobdiff - polyp/iochannel.c
Make the whole stuff LGPL only
[pulseaudio] / polyp / iochannel.c
index 69d381f4e546c54f6da44879ce119c069456286d..b93860a586ad46fc918476ae0087e4b4c9fcb007 100644 (file)
@@ -4,17 +4,17 @@
   This file is part of polypaudio.
  
   polypaudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published
-  by the Free Software Foundation; either version 2 of the License,
-  or (at your option) any later version.
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
  
   polypaudio is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
+  Lesser General Public License for more details.
  
-  You should have received a copy of the GNU General Public License
-  along with polypaudio; if not, write to the Free Software
+  You should have received a copy of the GNU Lesser General Public
+  License along with polypaudio; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.
 ***/
@@ -31,6 +31,7 @@
 #include "iochannel.h"
 #include "util.h"
 #include "socket-util.h"
+#include "xmalloc.h"
 
 struct pa_iochannel {
     int ifd, ofd;
@@ -45,50 +46,61 @@ struct pa_iochannel {
     
     int no_close;
 
-    void* input_source, *output_source;
+    struct pa_io_event* input_event, *output_event;
 };
 
 static void enable_mainloop_sources(struct pa_iochannel *io) {
     assert(io);
 
-    if (io->input_source == io->output_source) {
-        enum pa_mainloop_api_io_events e = PA_MAINLOOP_API_IO_EVENT_NULL;
-        assert(io->input_source);
+    if (io->input_event == io->output_event && io->input_event) {
+        enum pa_io_event_flags f = PA_IO_EVENT_NULL;
+        assert(io->input_event);
         
         if (!io->readable)
-            e |= PA_MAINLOOP_API_IO_EVENT_INPUT;
+            f |= PA_IO_EVENT_INPUT;
         if (!io->writable)
-            e |= PA_MAINLOOP_API_IO_EVENT_OUTPUT;
+            f |= PA_IO_EVENT_OUTPUT;
 
-        io->mainloop->enable_io(io->mainloop, io->input_source, e);
+        io->mainloop->io_enable(io->input_event, f);
     } else {
-        if (io->input_source)
-            io->mainloop->enable_io(io->mainloop, io->input_source, io->readable ? PA_MAINLOOP_API_IO_EVENT_NULL : PA_MAINLOOP_API_IO_EVENT_INPUT);
-        if (io->output_source)
-            io->mainloop->enable_io(io->mainloop, io->output_source, io->writable ? PA_MAINLOOP_API_IO_EVENT_NULL : PA_MAINLOOP_API_IO_EVENT_OUTPUT);
+        if (io->input_event)
+            io->mainloop->io_enable(io->input_event, io->readable ? PA_IO_EVENT_NULL : PA_IO_EVENT_INPUT);
+        if (io->output_event)
+            io->mainloop->io_enable(io->output_event, io->writable ? PA_IO_EVENT_NULL : PA_IO_EVENT_OUTPUT);
     }
 }
 
-static void callback(struct pa_mainloop_api* m, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void callback(struct pa_mainloop_api* m, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
     struct pa_iochannel *io = userdata;
     int changed = 0;
-    assert(m && fd >= 0 && events && userdata);
+    assert(m && e && fd >= 0 && userdata);
 
-    if ((events & PA_MAINLOOP_API_IO_EVENT_HUP) && !io->hungup) {
+    if ((f & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) && !io->hungup) {
         io->hungup = 1;
         changed = 1;
-    }
-    
-    if ((events & PA_MAINLOOP_API_IO_EVENT_INPUT) && !io->readable) {
-        io->readable = 1;
-        changed = 1;
-        assert(id == io->input_source);
-    }
-    
-    if ((events & PA_MAINLOOP_API_IO_EVENT_OUTPUT) && !io->writable) {
-        io->writable = 1;
-        changed = 1;
-        assert(id == io->output_source);
+
+        if (e == io->input_event) {
+            io->mainloop->io_free(io->input_event);
+            io->input_event = NULL;
+        }
+
+        if (e == io->output_event) {
+            io->mainloop->io_free(io->output_event);
+            io->output_event = NULL;
+        }
+    } else {
+
+        if ((f & PA_IO_EVENT_INPUT) && !io->readable) {
+            io->readable = 1;
+            changed = 1;
+            assert(e == io->input_event);
+        }
+        
+        if ((f & PA_IO_EVENT_OUTPUT) && !io->writable) {
+            io->writable = 1;
+            changed = 1;
+            assert(e == io->output_event);
+        }
     }
 
     if (changed) {
@@ -103,7 +115,7 @@ struct pa_iochannel* pa_iochannel_new(struct pa_mainloop_api*m, int ifd, int ofd
     struct pa_iochannel *io;
     assert(m && (ifd >= 0 || ofd >= 0));
 
-    io = malloc(sizeof(struct pa_iochannel));
+    io = pa_xmalloc(sizeof(struct pa_iochannel));
     io->ifd = ifd;
     io->ofd = ofd;
     io->mainloop = m;
@@ -115,23 +127,23 @@ struct pa_iochannel* pa_iochannel_new(struct pa_mainloop_api*m, int ifd, int ofd
     io->hungup = 0;
     io->no_close = 0;
 
+    io->input_event = io->output_event = NULL;
+
     if (ifd == ofd) {
         assert(ifd >= 0);
         pa_make_nonblock_fd(io->ifd);
-        io->input_source = io->output_source = m->source_io(m, ifd, PA_MAINLOOP_API_IO_EVENT_BOTH, callback, io);
+        io->input_event = io->output_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT|PA_IO_EVENT_OUTPUT, callback, io);
     } else {
 
         if (ifd >= 0) {
             pa_make_nonblock_fd(io->ifd);
-            io->input_source = m->source_io(m, ifd, PA_MAINLOOP_API_IO_EVENT_INPUT, callback, io);
-        } else
-            io->input_source = NULL;
+            io->input_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT, callback, io);
+        }
 
         if (ofd >= 0) {
             pa_make_nonblock_fd(io->ofd);
-            io->output_source = m->source_io(m, ofd, PA_MAINLOOP_API_IO_EVENT_OUTPUT, callback, io);
-        } else
-            io->output_source = NULL;
+            io->output_event = m->io_new(m, ofd, PA_IO_EVENT_OUTPUT, callback, io);
+        }
     }
 
     return io;
@@ -140,29 +152,29 @@ struct pa_iochannel* pa_iochannel_new(struct pa_mainloop_api*m, int ifd, int ofd
 void pa_iochannel_free(struct pa_iochannel*io) {
     assert(io);
 
+    if (io->input_event)
+        io->mainloop->io_free(io->input_event);
+    if (io->output_event && (io->output_event != io->input_event))
+        io->mainloop->io_free(io->output_event);
+
     if (!io->no_close) {
         if (io->ifd >= 0)
             close(io->ifd);
         if (io->ofd >= 0 && io->ofd != io->ifd)
             close(io->ofd);
     }
-
-    if (io->input_source)
-        io->mainloop->cancel_io(io->mainloop, io->input_source);
-    if (io->output_source && (io->output_source != io->input_source))
-        io->mainloop->cancel_io(io->mainloop, io->output_source);
     
-    free(io);
+    pa_xfree(io);
 }
 
 int pa_iochannel_is_readable(struct pa_iochannel*io) {
     assert(io);
-    return io->readable;
+    return io->readable || io->hungup;
 }
 
 int pa_iochannel_is_writable(struct pa_iochannel*io) {
     assert(io);
-    return io->writable;
+    return io->writable && !io->hungup;
 }
 
 int pa_iochannel_is_hungup(struct pa_iochannel*io) {
@@ -184,7 +196,6 @@ ssize_t pa_iochannel_write(struct pa_iochannel*io, const void*data, size_t l) {
 
 ssize_t pa_iochannel_read(struct pa_iochannel*io, void*data, size_t l) {
     ssize_t r;
-    
     assert(io && data && io->ifd >= 0);
     
     if ((r = read(io->ifd, data, l)) >= 0) {
@@ -220,3 +231,4 @@ int pa_iochannel_socket_set_sndbuf(struct pa_iochannel *io, size_t l) {
     assert(io);
     return pa_socket_set_sndbuf(io->ofd, l);
 }
+