basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/src/posix_port.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : posix_port.cpp
00004 * DESCRIPTION: Ports from file descriptors
00005 * COPYRIGHT  : (C) 2010  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00011 ******************************************************************************/
00012 
00013 #include <basix/posix_port.hpp>
00014 #include <sys/types.h>
00015 #include <sys/select.h>
00016 #include <sys/wait.h>
00017 #include <unistd.h>
00018 
00020 
00021 namespace mmx {
00022 
00023 /******************************************************************************
00024 * Constructor and destructor
00025 ******************************************************************************/
00026 
00027 extern table<int,int> out_count;
00028 extern table<int,int> in_count;
00029 
00030 posix_port_rep::posix_port_rep (int kind2, int fd2):
00031   kind (kind2), fd (fd2),
00032   buffer (""), pos (0), alive (true)
00033 {
00034   if ((kind & 1) != 0) out_count[fd]= out_count[fd] + 1;
00035   if ((kind & 2) != 0) in_count [fd]= in_count [fd] + 1;
00036 }
00037 
00038 posix_port_rep::~posix_port_rep () {
00039   if ((kind & 1) != 0) {
00040     out_count[fd]= out_count[fd] - 1;
00041     if (out_count[fd] == 0) reset (out_count, fd);
00042   }
00043   if ((kind & 2) != 0) {
00044     in_count [fd]= in_count [fd] - 1;
00045     if (in_count[fd] == 0) reset (in_count, fd);
00046   }
00047 }
00048 
00049 /******************************************************************************
00050 * Default reimplementations of virtual routines
00051 ******************************************************************************/
00052 
00053 void
00054 posix_port_rep::send (const char* s, nat n) {
00055   if (alive) {
00056     int err= ::write (fd, s, n);
00057     (void) err;
00058   }
00059 }
00060 
00061 void
00062 posix_port_rep::feed () {
00063   while (alive && wait (0)) {
00064     int r;
00065     char tempout[1024];
00066     r = ::read (fd, tempout, 1024);
00067     if (r == -1) {
00068       ::wait (NULL);
00069       ERROR ("read failed");
00070     }
00071     else if (r == 0) alive= false;
00072     else buffer << string (tempout, r);
00073   }
00074 }
00075 
00076 bool
00077 posix_port_rep::wait (int msecs) {
00078   //mmout << "Wait " << msecs << " ms on " << expression () << "\n";
00079   if ((kind & 2) == 0 || !alive) return false;
00080   fd_set in_fds;
00081   FD_ZERO (&in_fds);
00082   FD_SET (fd, &in_fds);
00083   
00084   nat nr;
00085   struct timeval tv;
00086   tv.tv_sec  = msecs / 1000;
00087   tv.tv_usec = 1000 * (msecs % 1000);
00088   if (msecs < 0) nr= select (fd + 1, &in_fds, NULL, NULL, NULL);
00089   else nr= select (fd + 1, &in_fds, NULL, NULL, &tv);
00090   //mmout << "Received " << nr << " on " << fd << "\n";
00091   return nr > 0;
00092 }
00093 
00094 /******************************************************************************
00095 * Global select
00096 ******************************************************************************/
00097 
00098 nat
00099 wait_port_event (int msecs) {
00100   //mmout << "Global wait " << msecs << " ms\n";
00101   int max_fd= 0;
00102 
00103   fd_set in_fds;
00104   FD_ZERO (&in_fds);
00105   for (iterator<int> it= entries (in_count); busy (it); ++it) {
00106     //mmout << "  Setting " << (*it) << "\n";
00107     FD_SET (*it, &in_fds);
00108     max_fd= max (max_fd, (*it) + 1);
00109   }
00110   
00111   nat nr;
00112   struct timeval tv;
00113   tv.tv_sec  = msecs / 1000;
00114   tv.tv_usec = 1000 * (msecs % 1000);
00115   if (msecs < 0) nr= select (max_fd, &in_fds, NULL, NULL, NULL);
00116   else nr= select (max_fd, &in_fds, NULL, NULL, &tv);
00117   //mmout << "Received " << nr << "\n";
00118   return nr;
00119 }
00120 
00121 } // namespace mmx
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines