示例#1
0
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);
	}

}
示例#2
0
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;
	}
}
示例#3
0
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;
}
示例#5
0
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);
	}
}
示例#6
0
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;
}