Revision: 40649
          http://brlcad.svn.sourceforge.net/brlcad/?rev=40649&view=rev
Author:   davidloman
Date:     2010-09-22 18:35:47 +0000 (Wed, 22 Sep 2010)

Log Message:
-----------
Implemented PortalManager main loop using a select() statement.  This forced 
the tracking of FD<->Portal associations to prevent a iterative/loop lookup 
performance hit.

Modified Paths:
--------------
    rt^3/trunk/include/PortalManager.h
    rt^3/trunk/src/libNet/PortalManager.cxx

Modified: rt^3/trunk/include/PortalManager.h
===================================================================
--- rt^3/trunk/include/PortalManager.h  2010-09-22 18:32:28 UTC (rev 40648)
+++ rt^3/trunk/include/PortalManager.h  2010-09-22 18:35:47 UTC (rev 40649)
@@ -37,19 +37,19 @@
 class PortalManager : public ControlledThread
 {
 public:
-       PortalManager(quint32 port);
+       PortalManager(quint16 port);
        ~PortalManager();
 
 protected:
        void _run();
-       void _runLoopPass();
 
 private:
-       quint32 port;
+       quint16 port;
        PkgTcpServer* tcpServer;
 
        QMutex* portalsLock;
-       QList<Portal*>* portals;
+       QMap<int, Portal*>* fdPortalMap;
+
 };
 
 #endif

Modified: rt^3/trunk/src/libNet/PortalManager.cxx
===================================================================
--- rt^3/trunk/src/libNet/PortalManager.cxx     2010-09-22 18:32:28 UTC (rev 
40648)
+++ rt^3/trunk/src/libNet/PortalManager.cxx     2010-09-22 18:35:47 UTC (rev 
40649)
@@ -22,17 +22,17 @@
  * Brief description
  *
  */
-
+#include "brlcad/bu.h"
 #include "Portal.h"
 #include "PortalManager.h"
 #include "NetMsgFactory.h"
 #include "PkgTcpClient.h"
 
-PortalManager::PortalManager(quint32 port) : ControlledThread("PortalManager")
+PortalManager::PortalManager(quint16 port) : ControlledThread("PortalManager")
 {
   this->port = port;
   this->tcpServer = new PkgTcpServer();
-  this->portals = new QList<Portal*>();
+  this->fdPortalMap = new QMap<int, Portal*>();
   this->portalsLock = new QMutex();
 }
 
@@ -41,44 +41,143 @@
 }
 
 void
-ControlledThread::_run()
+PortalManager::_run()
 {
+  fd_set masterfds;
+  fd_set readfds;
+  fd_set writefds;
+  fd_set exceptionfds;
+  int fdmax;
 
-  while (this->runCmd)
-    {
-      this->_runLoopPass();
-    }
-}
+  FD_ZERO(&masterfds);
+  FD_ZERO(&readfds);
+  FD_ZERO(&writefds);
+  FD_ZERO(&exceptionfds);
 
-void
-PortalManager::_runLoopPass()
-{
-  PkgTcpClient* client = (PkgTcpClient*) this->tcpServer->waitForClient(123);
 
-  if (client != 0) {
-    //Handle new client here.
-    Portal* newPortal = new Portal(client);
-    this->portalsLock->lock();
-    this->portals->append(newPortal);
-    this->portalsLock->unlock();
+  int listener = this->tcpServer->listen(this->port);
+  if (listener < 0) {
+      bu_log("PortalManager failed to listen\n");
+      return;
   }
 
-  //regardless of new client or not, process existing portals
-  QMutexLocker locker(this->portalsLock);
+  FD_SET(listener, &masterfds);
+  fdmax = listener;
 
-  for (int i = 0; i < this->portals->size(); ++i) {
-    Portal* p = this->portals->at(i);
+  while (this->runCmd) {
+    readfds = masterfds;
+    writefds = masterfds;
+    exceptionfds = masterfds;
 
-    int retval = p->sendRecv();
+    //Shelect!!
+    int retval = select(fdmax+1, &readfds, &writefds, &exceptionfds, NULL);
+    if(retval <0) {
+      //got a selector error
 
-    if (retval <= 0) {
-      //disconnect this portal
-      continue;
+/*      if(revtal == EABDF) {
+        bu_log("Selector Error: EBADF: An invalid file descriptor was given in 
one of the sets. (Perhaps a file descriptor that was already closed, or one on 
which an error has occurred.)\n");
+       } else if (retval == EINTR) {
+         bu_log("Selector Error: EINTR: A signal was caught.\n");
+       } else if (retval == EINVAL) {
+         bu_log("Selector Error: EINVAL: nfds is negative or the value 
contained within timeout is invalid.\n");
+       } else if (retval == ENOMEM) {
+         bu_log("Selector Error: ENOMEM: unable to allocate memory for 
internal tables.\n");
+       }*/
+
+      bu_log("Selector Error.\n");
+
+      break;
     }
 
-  }
-}
+      for (int i = 0; i <= fdmax; ++i) {
+                       if (FD_ISSET(i, &exceptionfds)) {
+                               //TODO handle exceptions
+                               perror("Exception on FIleDescriptor");
+                       }
+                       if (FD_ISSET(i, &readfds)) {
+                               //If we are 'reading' on listener
+                               if (i == listener) {
+                                       PkgTcpClient* client = (PkgTcpClient*) 
this->tcpServer->waitForClient(42);
 
+                                       if (client == 0) {
+                                               bu_log("Error on accepting new 
client.\n");
+                                       } else {
+                                               //Handle new client here.
+                                               Portal* newPortal = new 
Portal(client);
+                                               this->portalsLock->lock();
+                                               int newFD = 
newPortal->pkgClient->getFileDescriptor();
+                                               
this->fdPortalMap->insert(newFD, newPortal);
+                                               this->portalsLock->unlock();
+                                       }
+
+                                       //else we are plain reading.
+                               } else {
+                                       //Portal->read here.
+                                       if (this->fdPortalMap->contains(i)) {
+                        this->portalsLock->lock();
+                                               int readResult = 
this->fdPortalMap->value(i)->read();
+                        this->portalsLock->unlock();
+
+                                               if (readResult == 0) {
+                                                       bu_log("Lost connection 
to remote host.\n");
+                                                       close(i);
+                                                       FD_CLR(i, &masterfds);
+                                                       continue;
+
+                                               } else if (readResult < 0) {
+                            bu_log("Error on read, dropping connection to 
remote host.\n");
+                                                       close(i);
+                                                       FD_CLR(i, &masterfds);
+                                                       continue;
+
+                                               }
+
+                                       } else {
+                        bu_log("Attempting to read from FD not associated with 
a Portal, dropping connection to remote host.\n");
+                                               //Deal with unmapped file 
Descriptor
+                                               close(i);
+                                               FD_CLR(i, &masterfds);
+                                               continue;
+                                       }
+                               }
+                       }
+                       if (FD_ISSET(i, &writefds)) {
+                               //Portal->write here.
+                               if (this->fdPortalMap->contains(i)) {
+                                       this->portalsLock->lock();
+                                       int readResult = 
this->fdPortalMap->value(i)->write();
+                                       this->portalsLock->unlock();
+
+                                       if (readResult == 0) {
+                                               bu_log("Lost connection to 
remote host.\n");
+                                               close(i);
+                                               FD_CLR(i, &masterfds);
+                                               continue;
+
+                                       } else if (readResult < 0) {
+                                               bu_log(
+                                                               "Error on 
write, dropping connection to remote host.\n");
+                                               close(i);
+                                               FD_CLR(i, &masterfds);
+                                               continue;
+
+                                       }
+
+                               } else {
+                                       bu_log(
+                                                       "Attempting to write to 
FD not associated with a Portal, dropping connection to remote host.\n");
+                                       //Deal with unmapped file Descriptor
+                                       close(i);
+                                       FD_CLR(i, &masterfds);
+                                       continue;
+                               }
+                       }
+               } //end FOR
+
+
+    } //end while
+}//end fn
+
 // Local Variables:
 // tab-width: 8
 // mode: C++


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to