, , . 14.3 . , TimeBeep., Web-.
/
/, NT-, / . , , , 11 12, , . , .
, , , 1000. 1000 , . , 1 , 1000 1 , , - .[35] , , , , 9, . , .
/, , ( ). ; , .
, / , . - , /. .
/ .
/
CreateCompletionPort. .
HANDLE CreateIoCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort, DWORD CompletionKey, DWORD NumberOfConcurrentThreads);
|
|
/ , OVERLAPPED. FileHandle , . INVALID_DESCRIPTOR_HANDLE, / . , ExistingCompletionPort, NULL.
ExistingCompletionPort , , , . , NULL.
CompletionKey , FileHandle. , , .
NumberOfConcurrentThreads , . , , , . 0, , .
, /, . CreateCompletionPort . , , . , , , , .
, ReadFileEx WriteFileEx. Microsoft , .
/
/ , , ReadFile WriteFile OVERLAPPED ( ). / .
/, , , GetQueueCompletionStatus (completion port). , , , , , .
, , . . , , .
(time-out).
|
|
BOOL GetQueuedCompletionStatus(HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred, LPDWORD lpCompletionKey, LPOVERLAPPED *lpOverlapped, DWORD dwMilliseconds);
, /. , 14.4 , atouMTCP, Web-. , , (hEvent) OVERLAPPED; . , , .
/
, GetQueueCompletionStatus. PostQueueCompletionStatus.
BOOL PostQueuedCompletionStatus(HANDLE CompletionPort, DWORD dwNumberOfBytesTransferred, DWORD dwCompletionKey, LPOVERLAPPED lpOverlapped);
, , , 1. , , , , .
/
9 , , , .
serverSK ( 12.2) serverNP ( 11.3). , , , , . , /, . , , , . , . 14.6 , Web-.
, . (work items) (. 10) . , 10.5.
: , /
14.4 serverNP ( 11.3), /. , , . , ConnectNamedPipe. , , . , , . , OVERLAPPED 1.
|
|
, , . , 12. , , , .
, .
14.4. serverCP: ,
/* 14. ServerCP. .
, .
: Server [ ]. */
#include "EvryThng.h"
#include "ClntSrvr.h"
/* . */
typedef struct { /*, */
HANDLE hNp; /* */
REQUEST Req; /* ReadFile ConnectNamedPipe. */
DWORD Type; /* 0 ConnectNamedPipe; 1 ReadFile. */
OVERLAPPED Ov;
} CP_KEY;
static CP_KEY Key[MAX_CLIENTS_CP]; /* . */
/* */
_tmain(int argc, LPTSTR argv[]) {
HANDLE hCp, hMonitor, hSrvrThread[MAXCLIENTS];
DWORD iNp, iTh, MonitorId, ThreadId;
THREAD_ARG ThArgs[MAX_SERVER_TH];
/**/
hCp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, MAX_SERVER_TH);
/* */
/* , . */
/* , */
/* . */
for (iNp = 0; iNp < MAX_CLIENTS_CP; iNp++) {
memset(&Key[iNp], 0, sizeof(CP_KEY));
Key[iNp].hNp = CreateNamedPipe(SERVER_PIPE, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE | PIPE_WAIT, MAX_CLIENTS_CP, 0, 0, INFINITE, pNPSA);
CreateIoCompletionPort(Key[iNp].hNp, hCp, iNp, MAX_SERVER_TH + 2);
Key[iNp].Ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ConnectNamedPipe(Key[iNp].hNp, &Key[iNp].Ov);
}
/* .*/
for (iTh = 0; iTh < MAX_SERVER_TH; iTh++) {
ThArgs[iTh].hCompPort = hCp;
ThArgs[iTh].ThreadNo = iTh;
GetTempFileName(_T("."), _T("CLP"), 0, ThArgs[iTh].TmpFileName);
hSrvrThread[iTh] = (HANDLE)_beginthreadex (NULL, 0, Server, &ThArgs[iTh], 0, &ThreadId);
}
/* " ". */
/* */
return 0;
}
static DWORD WINAPI Server(LPTHREAD_ARG pThArg)
/* .
. */
{
HANDLE hCp, hTmpFile = INVALID_HANDLE_VALUE;
HANDLE hWrEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DWORD nXfer, KeyIndex, ServerNumber;
/* */
BOOL Success, Disconnect, Exit = FALSE;
LPOVERLAPPED pOv;
OVERLAPPED ovResp = {0, 0, 0, 0, hWrEvent}; /* .*/
/* , . , . */
ovResp.hEvent = (HANDLE)((DWORD)hWrEvent | 0x1);
|
|
GetStartupInfo(&StartInfoCh);
hCp = pThArg->hCompPort;
ServerNumber = pThArg->ThreadNo;
while(!ShutDown &&!Exit) __try {
Success = FALSE; /* . */
Disconnect = FALSE;
GetQueuedCompletionStatus(hCp, &nXfer, &KeyIndex, &pOv, INFINITE);
if (Key [KeyIndex].Type == 0) { /* . */
/* . */
hTmpFile = CreateFile(pThArg->TmpFileName, /* */);
Key[KeyIndex].Type = 1;
Disconnect =!ReadFile(Key[KeyIndex].hNp, &Key[KeyIndex].Req, RQ_SIZE, &nXfer, &Key[KeyIndex].Ov) && GetLastError () == ERROR_HANDLE_EOF; /* . */
if (Disconnect) continue;
Success = TRUE;
} else {
/* . . */
ShutDown = ShutDown || (_tcscmp (Key[KeyIndex].Req.Record, ShutRqst) == 0);
if (ShutDown) continue;
/* . */
/* */
/* . . */
fp = _tfopen(pThArg->TmpFileName, _T("r"));
Response.Status = 0;
/* , . */
while(_fgetts(Response.Record, MAX_RQRS_LEN, fp)!= NULL) {
WriteFile(Key [KeyIndex].hNp, &Response, RS_SIZE, &nXfer, &ovResp);
WaitForSingleObject(hWrEvent, INFINITE);
}
fclose(fp);
/* . */
SetFilePointer(hTmpFile, 0, NULL, FILE_BEGIN);
SetEndOfFile(hTmpFile);
/* . */
Response.Status = 1;
strcpy(Response.Record, "");
WriteFile(Key[KeyIndex].hNp, &Response, RS_SIZE, &nXfer, &ovResp);
WaitForSingleObject(hWrEvent, INFINITE);
/* . .*/
Disconnect =!ReadFile(Key[KeyIndex].hNp, &Key[KeyIndex].Req, RQ_SIZE, &nXfer, &Key[KeyIndex].Ov) && GetLastError() == ERROR_HANDLE_EOF; /* */
if (Disconnect) continue;
Success = TRUE;
}
} __finally {
if (Disconnect) {
/* . */
Key[KeyIndex].Type = 0;
DisconnectNamedPipe(Key[KeyIndex].hNp);
ConnectNamedPipe(Key[KeyIndex].hNp, &Key[KeyIndex].Ov);
}
if (!Success) {
ReportError(_T(" "), 0, TRUE);
Exit = TRUE;
}
}
FlushFileBuffers(Key[KeyIndex].hNp);
DisconnectNamedPipe(Key[KeyIndex].hNp);
CloseHandle(hTmpFile);
/* */
_endthreadex(0);
return 0;
/* . */
}
/ Windows . , , , , Windows 9x. , , /. , .
/ , " " . / , , .
, / .
/ , /, , atouMTCP, Web-, - , . , .
UNIX Pthreads, .
System V UNIX / .
|
|
BSD 4.3 , , (SIGIO). O_ASYNC. .