/** * Process all active socket requests. * * This is called under the server thread or server AO. * * @param aSelect(output): True if we need to do another Select call. * @param aNfds(output): Value = 1 + maximum socket handle for all sockets * that we are monitoring with the select call. */ void OsclSocketServI::ProcessSocketRequests(bool &aSelect, int &aNfds) { //process all active requests aSelect = false; TOsclSocket maxsocket = 0; aNfds = (int)maxsocket + 1; // Pick up new requests from the app thread. iSockServRequestList.Lock(); { iSockServRequestList.GetNewRequests(); //flush any data on the loopback socket. iLoopbackSocket.Read(); } iSockServRequestList.Unlock(); if (iSockServRequestList.iActiveRequests.empty()) { //nothing to do! return; } //Make a pass through the open request list and cancel or process each request. uint32 i; for (i = 0;i < iSockServRequestList.iActiveRequests.size();i++) { OsclSocketServRequestQElem* elem = &iSockServRequestList.iActiveRequests[i]; if (elem->iCancel) { //Request was canceled elem->iSocketRequest->Complete(elem, OSCL_REQUEST_ERR_CANCEL); } else if (!IsServConnected()) { //Server died or was closed. elem->iSocketRequest->Complete(elem, OSCL_REQUEST_ERR_GENERAL , (iServError) ? iServError : PVSOCK_ERR_SERV_NOT_CONNECTED); } else { //These routines will start the request, or else process //the results of prior select call, and also set the select //flags for the next call. elem->iSelect = 0; switch (elem->iSocketRequest->Fxn()) { case EPVSocketShutdown: elem->iSocketRequest->iSocketI->ProcessShutdown(elem); break; case EPVSocketConnect: elem->iSocketRequest->iSocketI->ProcessConnect(elem); break; case EPVSocketAccept: elem->iSocketRequest->iSocketI->ProcessAccept(elem); break; case EPVSocketSend: elem->iSocketRequest->iSocketI->ProcessSend(elem); break; case EPVSocketSendTo: elem->iSocketRequest->iSocketI->ProcessSendTo(elem); break; case EPVSocketRecv: elem->iSocketRequest->iSocketI->ProcessRecv(elem); break; case EPVSocketRecvFrom: elem->iSocketRequest->iSocketI->ProcessRecvFrom(elem); break; default: OSCL_ASSERT(0); break; } } } //Zero out any old select set FD_ZERO(&iReadset); FD_ZERO(&iWriteset); FD_ZERO(&iExceptset); LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Clearing select set")); //Now make a pass to either delete the request or collate the select flags. for (i = 0;i < iSockServRequestList.iActiveRequests.size();) { OsclSocketServRequestQElem* elem = &iSockServRequestList.iActiveRequests[i]; if (elem->iSocketRequest) { //request is still active i++; if (elem->iSelect > 0) { //Need to do a select call for this socket if (!aSelect) aSelect = true; TOsclSocket osock = elem->iSocketRequest->iSocketI->Socket(); if (osock > maxsocket) { LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Setting Maxsocket to %d", osock)); maxsocket = osock; } //Add the socket to the select set. Keep in mind there can be multiple requests //per socket, so check whether the socket is already added before adding. if ((elem->iSelect & OSCL_READSET_FLAG) == OSCL_READSET_FLAG && !(FD_ISSET(osock, &iReadset))) { FD_SET(osock, &iReadset); LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Setting Readset for %d", osock)); } if ((elem->iSelect & OSCL_WRITESET_FLAG) == OSCL_WRITESET_FLAG && !(FD_ISSET(osock, &iWriteset))) { FD_SET(osock, &iWriteset); LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Setting Writeset for %d", osock)); } if ((elem->iSelect & OSCL_EXCEPTSET_FLAG) == OSCL_EXCEPTSET_FLAG && !(FD_ISSET(osock, &iExceptset))) { FD_SET(osock, &iExceptset); LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Setting Exceptset for %d", osock)); } } } else { //request is complete and can be deleted. iSockServRequestList.iActiveRequests.erase(elem); } } //also monitor the loopback socket if we're going to call select. iLoopbackSocket.ProcessSelect(aSelect, maxsocket); if (aSelect) { aNfds = (int)(maxsocket + 1); } LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Select %d, NFDS %d", aSelect, aNfds)); }
void OsclSocketServI::ProcessSocketRequests() #endif { //process all active requests #if PV_SOCKET_SERVER_SELECT //keep track of max socket handle to monitor. TOsclSocket maxsocket = 0; aNfds = (int)maxsocket + 1; //save input handle count, then clear it until the next select operation. int nhandles = aNhandles; aNhandles = 0; #endif // Pick up new requests from the app thread. START_SERVI_STATS2(EServiProc_Queue); iSockServRequestList.Lock(); { iSockServRequestList.GetNewRequests(); #if PV_SOCKET_SERVER_SELECT_LOOPBACK_SOCKET //flush any data on the loopback socket. iLoopbackSocket.Read(); #endif } iSockServRequestList.Unlock(); END_SERVI_STATS2(EServiProc_Queue); if (iSockServRequestList.iActiveRequests.empty()) { //nothing to do! return; } //Make a pass through the open request list and cancel or process each request. START_SERVI_STATS2(EServiProc_Loop); uint32 i; for (i = 0; i < iSockServRequestList.iActiveRequests.size(); i++) { OsclSocketServRequestQElem* elem = &iSockServRequestList.iActiveRequests[i]; if (elem->iCancel) { //Request was canceled START_SERVI_STATS2(EServiProcLoop_Cancel); elem->iSocketRequest->Complete(elem, OSCL_REQUEST_ERR_CANCEL); END_SERVI_STATS2(EServiProcLoop_Cancel); } else if (!IsServConnected()) { //Server died or was closed. START_SERVI_STATS2(EServiProcLoop_Closed); elem->iSocketRequest->Complete(elem, OSCL_REQUEST_ERR_GENERAL , (iServError) ? iServError : PVSOCK_ERR_SERV_NOT_CONNECTED); END_SERVI_STATS2(EServiProcLoop_Closed); } #if PV_SOCKET_SERVER_SELECT else if (nhandles == 0 && elem->iSelect) { //we're monitoring this socket but there is no current //socket activity-- just keep waiting. ; } #endif else { //These routines will start the request, or else process //the results of prior select call, and also set the select //flags for the next call. switch (elem->iSocketRequest->Fxn()) { case EPVSocketShutdown: START_SERVI_STATS2(EServiProcLoop_Shutdown); elem->iSocketRequest->iSocketI->ProcessShutdown(elem); END_SERVI_STATS2(EServiProcLoop_Shutdown); break; case EPVSocketConnect: START_SERVI_STATS2(EServiProcLoop_Connect); elem->iSocketRequest->iSocketI->ProcessConnect(elem); END_SERVI_STATS2(EServiProcLoop_Connect); break; case EPVSocketAccept: START_SERVI_STATS2(EServiProcLoop_Accept); elem->iSocketRequest->iSocketI->ProcessAccept(elem); END_SERVI_STATS2(EServiProcLoop_Accept); break; case EPVSocketSend: START_SERVI_STATS2(EServiProcLoop_Send); elem->iSocketRequest->iSocketI->ProcessSend(elem); END_SERVI_STATS2(EServiProcLoop_Send); break; case EPVSocketSendTo: START_SERVI_STATS2(EServiProcLoop_SendTo); elem->iSocketRequest->iSocketI->ProcessSendTo(elem); END_SERVI_STATS2(EServiProcLoop_SendTo); break; case EPVSocketRecv: START_SERVI_STATS2(EServiProcLoop_Recv); elem->iSocketRequest->iSocketI->ProcessRecv(elem); END_SERVI_STATS2(EServiProcLoop_Recv); break; case EPVSocketRecvFrom: START_SERVI_STATS2(EServiProcLoop_RecvFrom); elem->iSocketRequest->iSocketI->ProcessRecvFrom(elem); END_SERVI_STATS2(EServiProcLoop_RecvFrom); break; default: OSCL_ASSERT(0); break; } } } END_SERVI_STATS2(EServiProc_Loop); //Zero out any old select set START_SERVI_STATS2(EServiProc_Fdset); #if PV_SOCKET_SERVER_SELECT FD_ZERO(&iReadset); FD_ZERO(&iWriteset); FD_ZERO(&iExceptset); #endif LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Clearing select set")); //Now make a pass to either delete the request or collate the select flags. for (i = 0; i < iSockServRequestList.iActiveRequests.size();) { OsclSocketServRequestQElem* elem = &iSockServRequestList.iActiveRequests[i]; if (elem->iSocketRequest) { //request is still active i++; #if PV_SOCKET_SERVER_SELECT if (elem->iSelect > 0) { //Need to do a select call for this socket TOsclSocket osock = elem->iSocketRequest->iSocketI->Socket(); if (osock > maxsocket) { LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Setting Maxsocket to %d", osock)); maxsocket = osock; } //Add the socket to the select set. Keep in mind there can be multiple requests //per socket, so check whether the socket is already added before adding. if ((elem->iSelect & OSCL_READSET_FLAG) == OSCL_READSET_FLAG && !(FD_ISSET(osock, &iReadset))) { FD_SET(osock, &iReadset); LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Setting Readset for %d", osock)); } if ((elem->iSelect & OSCL_WRITESET_FLAG) == OSCL_WRITESET_FLAG && !(FD_ISSET(osock, &iWriteset))) { FD_SET(osock, &iWriteset); LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Setting Writeset for %d", osock)); } if ((elem->iSelect & OSCL_EXCEPTSET_FLAG) == OSCL_EXCEPTSET_FLAG && !(FD_ISSET(osock, &iExceptset))) { FD_SET(osock, &iExceptset); LOGSERV((0, "OsclSocketServI::ProcessSocketRequests Setting Exceptset for %d", osock)); } } #endif } else { //request is complete and can be deleted. iSockServRequestList.iActiveRequests.erase(elem); } } END_SERVI_STATS2(EServiProc_Fdset); #if PV_SOCKET_SERVER_SELECT if (maxsocket) { #if PV_SOCKET_SERVER_SELECT_LOOPBACK_SOCKET //also monitor the loopback socket if we're going to call select. iLoopbackSocket.ProcessSelect(maxsocket); #endif //set Nfds to 1+maxsocket handle. aNfds = (int)maxsocket + 1; } LOGSERV((0, "OsclSocketServI::ProcessSocketRequests NFDS %d", aNfds)); #endif }