SocketStreamImplSIM.cpp

Go to the documentation of this file.
00001 /****************** <VPR heading BEGIN do not edit this line> *****************
00002  *
00003  * VR Juggler Portable Runtime
00004  *
00005  * Original Authors:
00006  *   Allen Bierbaum, Patrick Hartling, Kevin Meinert, Carolina Cruz-Neira
00007  *
00008  * -----------------------------------------------------------------
00009  * File:          $RCSfile$
00010  * Date modified: $Date: 2005-01-17 22:34:01 -0600 (Mon, 17 Jan 2005) $
00011  * Version:       $Revision: 16635 $
00012  * -----------------------------------------------------------------
00013  *
00014  ****************** <VPR heading END do not edit this line> ******************/
00015 
00016 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
00017  *
00018  * VR Juggler is (C) Copyright 1998-2005 by Iowa State University
00019  *
00020  * Original Authors:
00021  *   Allen Bierbaum, Christopher Just,
00022  *   Patrick Hartling, Kevin Meinert,
00023  *   Carolina Cruz-Neira, Albert Baker
00024  *
00025  * This library is free software; you can redistribute it and/or
00026  * modify it under the terms of the GNU Library General Public
00027  * License as published by the Free Software Foundation; either
00028  * version 2 of the License, or (at your option) any later version.
00029  *
00030  * This library is distributed in the hope that it will be useful,
00031  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00032  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00033  * Library General Public License for more details.
00034  *
00035  * You should have received a copy of the GNU Library General Public
00036  * License along with this library; if not, write to the
00037  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00038  * Boston, MA 02111-1307, USA.
00039  *
00040  *************** <auto-copyright.pl END do not edit this line> ***************/
00041 
00042 #include <vpr/vprConfig.h>
00043 
00044 #include <boost/concept_check.hpp>
00045 
00046 #include <vpr/Util/Assert.h>
00047 #include <vpr/Util/Debug.h>
00048 
00049 #include <vpr/md/SIM/Controller.h>
00050 #include <vpr/md/SIM/SocketManager.h>
00051 #include <vpr/md/SIM/IO/Socket/SocketStreamImplSIM.h>
00052 
00053 
00054 namespace vpr
00055 {
00056 
00057 vpr::ReturnStatus SocketStreamImplSIM::listen(const int backlog)
00058 {
00059    return vpr::sim::Controller::instance()->getSocketManager().listen(this, backlog);
00060 }
00061 
00062 vpr::ReturnStatus SocketStreamImplSIM::accept(SocketStreamImplSIM& clientSock,
00063                                               vpr::Interval timeout)
00064 {
00065    boost::ignore_unused_variable_warning(timeout);
00066    vpr::ReturnStatus status;
00067 
00068    mConnectorQueueMutex.acquire();
00069 
00070    if ( ! mConnectorQueue.empty() )
00071    {
00072       SocketStreamImplSIM* peer_ptr = mConnectorQueue.front();    // The peer requesting the connection
00073       mConnectorQueue.pop();
00074 
00075       mConnectorQueueMutex.release();
00076 
00077       vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
00078          << "SocketStreamImplSIM::accept() [" << mLocalAddr
00079          << "]: Got pending connector from " << peer_ptr->getLocalAddr()
00080          << "\n" << vprDEBUG_FLUSH;
00081 
00082       // -- Set known properties of the next socket
00083       clientSock.mRemoteAddr = peer_ptr->mLocalAddr;    // Get the remote node's address (it must have called bind, so this is final)
00084       clientSock.mOpen       = true;
00085       clientSock.mBlocking   = mBlocking;
00086       clientSock.setConnectState(peer_ptr);
00087 
00088       // Get an address for the new socket, bind it, and attach the socket to
00089       // the correct node.
00090       vpr::sim::Controller* controller = vpr::sim::Controller::instance();
00091       vpr::sim::SocketManager& sock_mgr = controller->getSocketManager();
00092       clientSock.mLocalAddr  = mLocalAddr;              // Start with local socket's address
00093       clientSock.mLocalAddr.setPort(0);                 // Clear port so that we get a unique one
00094       clientSock.bind();                                // Bind to a port (and assign to net node)
00095 
00096       // Now define the route for messages between the two sockets.
00097       // - Sets the path inside both sockets (path to the other socket)
00098       sock_mgr.findRoute(peer_ptr, clientSock.getHandle());
00099 
00100       peer_ptr->completeConnection(clientSock.getHandle());
00101 
00102       controller->addConnectionCompletionEvent(controller->getClock().getCurrentTime(),
00103                                                peer_ptr);
00104 
00105       // Make sure the peer's remote address has the right address.
00106       // Prior to this point, it has the port of the accepting socket.
00107       vprASSERT(peer_ptr->mRemoteAddr == clientSock.mLocalAddr && "Connector doesn't know peer's IP address");
00108    }
00109    else
00110    {
00111       mConnectorQueueMutex.release();
00112       status.setCode(vpr::ReturnStatus::WouldBlock);
00113    }
00114 
00115    return status;
00116 }
00117 
00118 vpr::ReturnStatus SocketStreamImplSIM::addConnector(vpr::SocketImplSIM* peerSock)
00119 {
00120    SocketStreamImplSIM* stream_remote;
00121 
00122    vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
00123       << "SocketStreamImplSIM::addConnector() [" << mLocalAddr
00124       << "]: Adding connector from " << peerSock->getLocalAddr() << "\n"
00125       << vprDEBUG_FLUSH;
00126 
00127    stream_remote   = dynamic_cast<SocketStreamImplSIM*>(peerSock);
00128 
00129    vprASSERT(NULL != stream_remote && "Tried to connect to a non-stream socket!");
00130 
00131    mConnectorQueueMutex.acquire();
00132    {
00133       mConnectorQueue.push(stream_remote);
00134    }
00135    mConnectorQueueMutex.release();
00136 
00137    return vpr::ReturnStatus(vpr::ReturnStatus::InProgress);
00138 }
00139 
00140 vpr::ReturnStatus SocketStreamImplSIM::isReadReady() const
00141 {
00142    vpr::ReturnStatus status(vpr::ReturnStatus::Fail);
00143 
00144    // To be able to read, we must be open, connected, and have a non-empty
00145    // queue of arrived messages.
00146    if ( isOpen() && isConnected() && (! mArrivedQueue.empty()) )
00147    {
00148       status.setCode(vpr::ReturnStatus::Succeed);
00149    }
00150 
00151    if ( isOpen() && getConnectorCount() > 0 )
00152    {
00153       status.setCode(vpr::ReturnStatus::Succeed);
00154    }
00155 
00156    return status;
00157 }
00158 
00159 vpr::ReturnStatus SocketStreamImplSIM::isWriteReady() const
00160 {
00161    vpr::ReturnStatus status;
00162 
00163    // We cannot write if we are not open or we not are connected.
00164    if ( ! isOpen() || ! isConnected() )
00165    {
00166       status.setCode(vpr::ReturnStatus::Fail);
00167    }
00168 
00169    return status;
00170 }
00171 
00172 } // End of vpr namespace

Generated on Thu Jan 4 10:52:11 2007 for VR Juggler Portable Runtime by  doxygen 1.5.1