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
1.5.1