void ConnectionManager::connectionReadyRead() { struct msghdr msg; struct iovec iov; TTRACE("ConnectionManager::connectionReadyRead"); /* Response data */ iov.iov_base = buffer.data(); iov.iov_len = buffer.length(); /* compose the message */ memset(&msg, 0, sizeof(msg)); msg.msg_iov = &iov; msg.msg_iovlen = 1; while(connectionFd >= 0) { int nread = recvmsg(connectionFd, &msg, MSG_DONTWAIT); if (nread == 0) { connectionClose(); return; } else if (nread < 0) { if (errno != EAGAIN) { TWARN("recvmsg error %s", strerror(errno)); //close(connFd); connectionClose(); } return; } receiveDatagram(buffer.data(), nread); } }
void ConnectionManager::sendDatagram(const char* buf, size_t len, int controlFd) { char control[sizeof(struct cmsghdr)+10]; struct msghdr msg; struct cmsghdr *cmsg; struct iovec iov; /* Response data */ iov.iov_base = const_cast<char*>(buf); iov.iov_len = len; /* compose the message */ memset(&msg, 0, sizeof(msg)); msg.msg_iov = &iov; msg.msg_iovlen = 1; /* send controlFd */ if (controlFd > 0) { msg.msg_control = control; msg.msg_controllen = sizeof(control); cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(controlFd)); memcpy(reinterpret_cast<void *>(CMSG_DATA(cmsg)), &controlFd, sizeof(controlFd)); msg.msg_controllen = cmsg->cmsg_len; } if (sendmsg(connectionFd, &msg, MSG_DONTWAIT) < 0) { TWARN("sendmsg error %s", strerror(errno)); connectionClose(); //close(connFd); return; } }
static void connectCompleteImpl(connection_t connection, int status) { connectionContext_t* pContext = connectionGetContext(connection); if (status != 0) { connectionClose(connection); connectionContextDelete(pContext, 0); }else { LOG(DEBUG, "got connect complete callback "); connectionConnect(connection); pContext->status = status_active; connectionSubmitRequests(pContext->pExternalServer, pContext); } }
// private functions RyConnection * RyProxyServer::_getConnection(int handle){ //QMutexLocker locker(&connectionOpMutex); //Q_UNUSED(locker) //QDateTime time = QDateTime::currentDateTime(); //qDebug()<<"getConnection:" // <<time.toMSecsSinceEpoch(); //if(!_cacheConnections.contains(handle)){ //qDebug()<<"_lastConnectionId"<<_lastConnectionId; _lastConnectionId++; QMutexLocker locker(&connectionOpMutex); QThread *newThread = new QThread(); RyConnection *connection = new RyConnection(handle,_lastConnectionId); _connections.append(connection); _threads[connection] = newThread; locker.unlock(); connect(connection,SIGNAL(idleTimeout()),SLOT(onConnectionIdleTimeout())); connect(connection,SIGNAL(pipeBegin(RyPipeData_ptr)), SLOT(onPipeBegin(RyPipeData_ptr))); connect(connection,SIGNAL(pipeComplete(RyPipeData_ptr)), SLOT(onPipeComplete(RyPipeData_ptr))); connect(connection,SIGNAL(pipeError(RyPipeData_ptr)), SLOT(onPipeError(RyPipeData_ptr))); connect(connection,SIGNAL(connectionClose()), SLOT(onConnectionClosed())); connect(connection,SIGNAL(pipeBegin(RyPipeData_ptr)), SIGNAL(pipeBegin(RyPipeData_ptr))); connect(connection,SIGNAL(pipeComplete(RyPipeData_ptr)), SIGNAL(pipeComplete(RyPipeData_ptr))); connect(connection,SIGNAL(pipeError(RyPipeData_ptr)), SIGNAL(pipeError(RyPipeData_ptr))); connection->moveToThread(newThread); connect(newThread,SIGNAL(started()),connection,SLOT(run())); connect(newThread,SIGNAL(finished()),SLOT(onThreadTerminated())); newThread->start(); /* qDebug()<<"=== create connection cost:" <<time.msecsTo(QDateTime::currentDateTime()) <<time.toMSecsSinceEpoch(); */ return connection; }
static void connectionContextDelete(connectionContext_t* pContext, int move) { if (pContext) { externalServer_t* pServer = pContext->pExternalServer; clusterMapImpl_t* pCMap = pServer->pClusterMap; request_t* pRequest = 0; LOG(DEBUG, "deleting connection context"); while ((pRequest = listRemoveLast(pContext->currentRequests)) != 0) { if (move) { //move the existing requests to another socket listAddFirst(pServer->unassignedRequests, pRequest); }else { //report error pCMap->resultHandler(pRequest->luaContext, pRequest->keyContext, -1, NULL); deleteRequest(pRequest); } } if (pContext->connection) { connectionClose(pContext->connection); } if (pContext->readStream) { dataStreamDelete(pContext->readStream); pContext->readStream = 0; } if (pContext->writeStream) { dataStreamDelete(pContext->writeStream); pContext->writeStream = 0; } if (pContext->parser) { responseParserDelete(pContext->parser); pContext->parser = 0; } if (pContext->currentRequests) { listFree(pContext->currentRequests); pContext->currentRequests = 0; } if (pContext->fallocator) { fallocatorDelete(pContext->fallocator); } FREE(pContext); } }
static int externalServerSubmit(externalServer_t* pServer, request_t* pRequest) { int returnValue = 0; connectionContext_t* pCContext = 0; connection_t newConnection = 0; listAddLast(pServer->unassignedRequests, pRequest); pCContext = listRemoveFirst(pServer->freeConnections); if (pCContext) { connectionWaitCancel(pCContext->connection, getGlobalEventBase()); } if (!pCContext) { //check if we have reached max concurrent connections limit // if not, create a new connection if (listGetSize(pServer->activeConnections) < MAX_CONCURRENT_CONNECTIONS) { LOG(DEBUG, "creating new external connection"); newConnection = connectionClientCreate(pServer->serverIP, pServer->serverPort, createConnectionHandler()); IfTrue(newConnection, ERR, "Error creating new connection to %s", pServer->serverName); //got a new connection pCContext = connectionContextCreate(newConnection, pServer); IfTrue(pCContext, ERR, "Error allocting memory for connection context"); connectionSetContext(newConnection, pCContext); newConnection = 0; int err = connectionConnect(pCContext->connection); IfTrue(err >= 0, ERR, "connect failed"); if (err == 1) { LOG(DEBUG, "waiting for connect to complete"); pCContext->status = status_connecting; connectionWaitForConnect(pCContext->connection, getGlobalEventBase()); goto OnSuccess; } }else { //if we have reached max connection limit, we will let the request rest //in the queue. Whenever one of the current connections get free, we will //use that to send the request. returnValue = 1; goto OnSuccess; } } if (pCContext) { pCContext->status = status_active; connectionSubmitRequests(pServer, pCContext); } goto OnSuccess; OnError: if (newConnection) { connectionClose(newConnection); } if (pCContext) { connectionContextDelete(pCContext, 0); } returnValue = 1; OnSuccess: return returnValue; }