Revision: 40736
http://brlcad.svn.sourceforge.net/brlcad/?rev=40736&view=rev
Author: davidloman
Date: 2010-09-28 15:02:53 +0000 (Tue, 28 Sep 2010)
Log Message:
-----------
Complete revamp of selector loop. Better logic and flow now. Added in
pkg_switch table generation to both incoming and outgoing connection logic.
Modified Paths:
--------------
rt^3/trunk/src/libNet/PortalManager.cxx
Modified: rt^3/trunk/src/libNet/PortalManager.cxx
===================================================================
--- rt^3/trunk/src/libNet/PortalManager.cxx 2010-09-28 15:01:34 UTC (rev
40735)
+++ rt^3/trunk/src/libNet/PortalManager.cxx 2010-09-28 15:02:53 UTC (rev
40736)
@@ -44,8 +44,13 @@
Portal*
PortalManager::connectToHost(QString host, quint16 port)
{
- PkgTcpClient* pkgc = (PkgTcpClient*
)this->tcpServer->connectToHost(host.toStdString(), port);
+ struct pkg_switch table[] = {
+ {PKG_MAGIC2, &(Portal::callbackSpringboard), "SpringBoard", NULL},
+ {0,0, (char*)0,0}
+ };
+ PkgTcpClient* pkgc = (PkgTcpClient*
)this->tcpServer->connectToHost(host.toStdString(), port, table);
+
if (pkgc == NULL) {
return NULL;
} else {
@@ -54,27 +59,32 @@
}
void
-PortalManager::_run()
-{
- struct timeval timeout;
- fd_set readfds;
- fd_set writefds;
- fd_set exceptionfds;
- int listener;
+PortalManager::_run() {
+ struct timeval timeout;
+ fd_set readfds;
+ fd_set writefds;
+ fd_set exceptionfds;
+ int listener = -1;
- this->masterFDSLock.lock();
- FD_ZERO(&masterfds);
- this->masterFDSLock.unlock();
+ this->masterFDSLock.lock();
+ FD_ZERO(&masterfds);
+ this->masterFDSLock.unlock();
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_ZERO(&exceptionfds);
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptionfds);
- if (this->port != 0) {
+ if (this->port != 0) {
listener = this->tcpServer->listen(this->port);
if (listener < 0) {
this->log->logERROR("PortalManager", "Failed to
listen");
return;
+ } else {
+ QString s("Listening on port: ");
+ s.append(QString::number(port));
+ s.append(" FD:");
+ s.append(QString::number(listener));
+ this->log->logERROR("PortalManager", s);
}
this->masterFDSLock.lock();
@@ -83,126 +93,169 @@
this->masterFDSLock.unlock();
}
- while (this->runCmd) {
- //Set values EVERY loop since select() on *nix modifies this.
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
+ while (this->runCmd) {
+ //Set values EVERY loop since select() on *nix modifies this.
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 500*1000;
+ this->masterFDSLock.lock();
+ readfds = masterfds;
+ //writefds = masterfds;
+ exceptionfds = masterfds;
+ this->masterFDSLock.unlock();
- this->masterFDSLock.lock();
- readfds = masterfds;
- writefds = masterfds;
- exceptionfds = masterfds;
- this->masterFDSLock.unlock();
+ //Shelect!!
+ this->log->logINFO("PortalManager", "At Select.");
+ int retval =
+ select(fdmax + 1, &readfds, NULL,
&exceptionfds, &timeout);
- //Shelect!!
- int retval = select(fdmax+1, &readfds, &writefds, NULL, &timeout);
+ QString out("Loop start. Select returned: ");
+ out.append(QString::number(retval));
+ out.append(". FD count: ");
+ out.append(QString::number(this->fdPortalMap->keys().size()));
+ out.append(". MAX FD: ");
+ out.append(QString::number(fdmax));
+ this->log->logINFO("PortalManager", out);
- QString out("Loop start. Select returned: ");
- out.append(QString::number(retval));
- this->log->logINFO("PortalManager", out);
+ //Save time on the loop:
+ if (retval == 0) {
+ //continue;
+ }
- //Save time on the loop:
- if (retval == 0) {
- continue;
- }
+ if (retval < 0) {
+ //got a selector error
- if(retval <0) {
- //got a selector error
+ /* 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");
+ }*/
-/* 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");
- }*/
+ this->log->logERROR("PortalManager", "Selector Error.");
- this->log->logERROR("PortalManager", "Selector Error.");
+ break;
+ }
- break;
- }
+ for (int i = 0; i <= fdmax; ++i) {
+ bool isaFD = FD_ISSET(i, &masterfds);
- for (int i = 0; i <= fdmax; ++i) {
- /*
- if (FD_ISSET(i, &exceptionfds)) {
+ //Don't muck with an FD that isn't ours!
+ if (!isaFD) {
+ continue;
+ }
+
+ //Simplify switching later with bools now
+ bool isListener = (i == listener);
+ bool readyRead = FD_ISSET(i, &readfds) && !isListener;
+ bool readyWrite = FD_ISSET(i, &writefds);
+ bool readyAccept = FD_ISSET(i, &readfds) && isListener;
+ bool readyException = FD_ISSET(i, &exceptionfds);
+
+ QString s("FD:");
+ s.append(QString::number(i));
+
+ if (isListener) {
+ s.append(" is the listener and");
+ }
+
+ s.append(" is on the: masterFDS");
+
+ if (readyRead) {
+ s.append(", readFDS");
+ }
+ if (readyWrite) {
+ s.append(", writeFDS");
+ }
+ if (readyException) {
+ s.append(", exceptionFDS");
+ }
+
+ log->logDEBUG("PortalManager", s);
+
+ //Handle exceptions
+ if (readyException) {
//TODO handle exceptions
perror("Exception on FileDescriptor");
}
-*/
- if (FD_ISSET(i, &readfds)) {
- this->log->logINFO("PortalManager", "Read On
Listener.");
+ Portal* p;
+ //Accept new connections:
+ if (readyAccept) {
+ log->logINFO("PortalManager", "Accept");
- //If we are 'reading' on listener
- if (port != 0 && i == listener) {
- PkgTcpClient* client = (PkgTcpClient*)
this->tcpServer->waitForClient(42);
+ struct pkg_switch table[] = { { PKG_MAGIC2,
+ &(Portal::callbackSpringboard),
"SpringBoard", NULL },
+ { 0, 0, (char*) 0, 0 } };
- if (client == 0) {
-
this->log->logERROR("PortalManager", "Error on accepting new client.");
- } else {
- //Handle new client here.
- this->makeNewPortal(client);
- }
+ PkgTcpClient* client =
+ (PkgTcpClient*)
this->tcpServer->waitForClient(table,
+ 42);
- //else we are plain reading.
+ if (client == 0) {
+ log->logERROR("PortalManager",
+ "Error on accepting new
client.");
} else {
- this->log->logINFO("PortalManager",
"Read On Normal FD.");
- //Portal->read here.
- if (this->fdPortalMap->contains(i)) {
- this->portalsLock->lock();
- int readResult =
this->fdPortalMap->value(i)->read();
- this->portalsLock->unlock();
+ //Handle new client here.
+ p = this->makeNewPortal(client);
+ p->sendGSNodeName();
+ }
+ }
- if (readResult == 0) {
- this->closeFD(i, "Lost
connection to remote host.");
- continue;
- } else if (readResult < 0) {
- this->closeFD(i, "Error
on read, dropping connection to remote host.");
- continue;
- }
+ //the only thing we want to do on the listener loop is
accept
+ if (isListener) {
+ continue;
+ }
- } else {
- //Deal with unmapped file
Descriptor
- this->closeFD(i, "Attempting to
read from FD not associated with a Portal, dropping connection to remote
host.");
- continue;
- }
+ //If we didnt get a portal from accepting, then get one
from the map
+ if (p == 0 && this->fdPortalMap->contains(i)) {
+ this->portalsLock->lock();
+ p = this->fdPortalMap->value(i);
+ this->portalsLock->unlock();
+ }
+
+ //Check, again, if we have a good portal.
+ if (p == 0) {
+ //Deal with unmapped file Descriptor
+ QString s("FD ");
+ s.append(QString::number(i));
+ s.append(" not associated with a Portal,
dropping connection.");
+ this->closeFD(i, s);
+ continue;
+ }
+
+ //read
+ if (readyRead) {
+ this->log->logINFO("PortalManager", "Read");
+
+ int readResult = p->read();
+
+ if (readResult == 0) {
+ this->closeFD(i, "Lost connection.");
+ continue;
+ } else if (readResult < 0) {
+ this->closeFD(i, "Error on read,
dropping connection.");
+ continue;
}
}
- /*
- * Do we really need Write checking?
- */
- if (FD_ISSET(i, &writefds)) {
+ //write
+ if (readyWrite) {
this->log->logINFO("PortalManager", "Write.");
- /*
- //Portal->write here.
- if (this->fdPortalMap->contains(i)) {
- this->portalsLock->lock();
- int readResult =
this->fdPortalMap->value(i)->write();
- this->portalsLock->unlock();
+ int retVal = p->flush();
+ bu_log("Flushed %d bytes.", retVal);
- if (readResult == 0) {
- this->closeFD(i,"Lost
connection to remote host.\n", &masterfds);
- continue;
- } else if (readResult < 0) {
- this->closeFD(i, "Error on
write, dropping connection to remote host.\n", &masterfds);
- continue;
- }
-
- } else {
- //Deal with unmapped file Descriptor
- this->closeFD(i,"Attempting to write to
FD not associated with a Portal, dropping connection to remote host.",
&masterfds);
+ if (retVal < 0) {
+ this->closeFD(i, "Error on write,
dropping connection.");
continue;
}
- */
}
-
} //end FOR
- } //end while
+ } //end while
}//end fn
@@ -220,16 +273,17 @@
this->fdPortalMap->insert(newFD, newPortal);
this->portalsLock->unlock();
+ QString s ("New Portal with FD: ");
+ s.append(QString::number(newFD));
+ log->logDEBUG("PortalManager", s);
+
//Check maxFD and update if needed.
if (newFD > fdmax) {
this->masterFDSLock.lock();
+ FD_SET(newFD, &masterfds);
fdmax = newFD;
this->masterFDSLock.unlock();
}
-
- //Send our name
- newPortal->sendGSNodeName();
-
return newPortal;
}
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