/* Search for a job that has available query slots and that match provided type. * If none is found, create a new one. Return the corresponding SELECTDATA, and * update provided SELECTDATA head, if required. */ LPSELECTDATA select_data_job_search (LPSELECTDATA *lppSelectData, SELECTTYPE EType) { LPSELECTDATA res; res = NULL; /* Search for job */ DEBUG_PRINT("Searching an available job for type %d", EType); res = *lppSelectData; while ( res != NULL && !( res->EType == EType && res->nQueriesCount < MAXIMUM_SELECT_OBJECTS ) ) { res = LIST_NEXT(LPSELECTDATA, res); } /* No matching job found, create one */ if (res == NULL) { DEBUG_PRINT("No job for type %d found, create one", EType); res = select_data_new(*lppSelectData, EType); *lppSelectData = res; } return res; }
/* Add a function to monitor console input */ LPSELECTDATA read_console_poll_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, HANDLE hFileDescr, LPVOID lpOrig) { LPSELECTDATA res; res = select_data_new(lpSelectData, SELECT_TYPE_CONSOLE_READ); res->funcWorker = read_console_poll; select_data_query_add(res, SELECT_MODE_READ, hFileDescr, lpOrig); return res; }
/* Add a function to monitor console input */ LPSELECTDATA read_console_poll_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, HANDLE hFileDescr, int lpOrigIdx, unsigned int uFlagsFd) { LPSELECTDATA res; res = select_data_new(lpSelectData, SELECT_TYPE_CONSOLE_READ); res->funcWorker = read_console_poll; select_data_query_add(res, SELECT_MODE_READ, hFileDescr, lpOrigIdx, uFlagsFd); return res; }
/* Add a function to monitor socket */ LPSELECTDATA socket_poll_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, HANDLE hFileDescr, int lpOrigIdx, unsigned int uFlagsFd) { LPSELECTDATA res; LPSELECTDATA candidate; DWORD i; LPSELECTQUERY aQueries; res = lpSelectData; candidate = NULL; aQueries = NULL; /* Polling socket can be done mulitple handle at the same time. You just need one worker to use it. Try to find if there is already a worker handling this kind of request. Only one event can be associated with a given socket which means that if a socket is in more than one of the fd_sets then we have to find that particular query and update EMode with the additional flag. */ DEBUG_PRINT("Scanning list of worker to find one that already handle socket"); /* Search for job */ DEBUG_PRINT("Searching for an available job for type %d for descriptor %d", SELECT_TYPE_SOCKET, hFileDescr); while (res != NULL) { if (res->EType == SELECT_TYPE_SOCKET) { i = res->nQueriesCount - 1; aQueries = res->aQueries; while (i >= 0 && aQueries[i].hFileDescr != hFileDescr) { i--; } /* If we didn't find the socket but this worker has available slots, store it */ if (i < 0) { if ( res->nQueriesCount < MAXIMUM_SELECT_OBJECTS) { candidate = res; } res = LIST_NEXT(LPSELECTDATA, res); } else { /* Previous socket query located -- we're finished */ aQueries = &aQueries[i]; break; } } else { res = LIST_NEXT(LPSELECTDATA, res); } } if (res == NULL) { res = candidate; /* No matching job found, create one */ if (res == NULL) { DEBUG_PRINT("No job for type %d found, create one", SELECT_TYPE_SOCKET); res = select_data_new(lpSelectData, SELECT_TYPE_SOCKET); res->funcWorker = socket_poll; res->nQueriesCount = 1; aQueries = &res->aQueries[0]; } else { aQueries = &(res->aQueries[res->nQueriesCount++]); } aQueries->EMode = EMode; aQueries->hFileDescr = hFileDescr; aQueries->lpOrigIdx = lpOrigIdx; aQueries->uFlagsFd = uFlagsFd; DEBUG_PRINT("Socket %x added", hFileDescr); } else { aQueries->EMode |= EMode; DEBUG_PRINT("Socket %x updated to %d", hFileDescr, aQueries->EMode); } return res; }