extern "C" APIRET APIENTRY _startServerThreads(void *handl) { int i,ii, id, idd; typedef void (*handler_t) (void *obj, int ncmd, int data, int threadNum); // id = _beginthread(TestTest,NULL, STACK_SIZE*16,NULL); //DosSleep(1000); //DosSleep(1000); // return; handler = (handler_t)handl; for(i=0;i < FREEPMS_MAX_NUM_THREADS;i++) { LSthreads.thread_id[i] = -1; } LSthreads.next_free = 0; M0: LSthreads.working = 0; // нужно для организации задержки ожидания запуска первого клиента idd = LSthreads.next_free; ThreadStart = 1; id = _beginthread(&Fs_ClientWork,NULL, THREAD_STACK_SIZE * 2, (void *) &idd); // ((void*) (void*)) //id = _beginthread( ((void(*) (void*))fix_asm_Fs_ClientWork), NULL, hack_thread_size, (void *) &idd); do { DosSleep(1); } while(ThreadStart == 1); while(__lxchg(&LSthreads.semaphore, LOCKED)) DosSleep(1); LSthreads.num++; LSthreads.thread_id[LSthreads.next_free] = id; for(i = 0; i < FREEPMS_MAX_NUM_THREADS; i++) { ii = (i + LSthreads.next_free) % FREEPMS_MAX_NUM_THREADS; if(LSthreads.thread_id[ii] == -1) { LSthreads.next_free = ii; break; } } ThreadStart = 3; __lxchg(&LSthreads.semaphore, UNLOCKED); return 0; }
_Inline VOID heapUnlock(VOID) { __lxchg(&isem, HEAP_UNLOCK); }
void /*_Optlink*/ Fs_ClientWork(void *param) { int i,rc, threadNum,id,idd; int ncmd,data; // char PipeName[256]; char str[512]; char buf[MAX_PIPE_BUF], bufout[MAX_PIPE_BUF]; _control87(EM_UNDERFLOW,EM_UNDERFLOW); int bla = 0; while(__lxchg(&LSthreads.semaphore, LOCKED)) DosSleep(1); //int volatile * a, int b) { /*printf("FIXME: builtin.h:%s (%d, %d)\n", __func__, *a, b);*/ //DosEnterCritSec(); /* int ret = 1; while(ret) { ret = 1; if(LSthreads.semaphore == 0 && LOCKED == 1) { LSthreads.semaphore = LOCKED; ret = 0; } if(LSthreads.semaphore == 1 && LOCKED == 0) { ret = 1; } for(double di=0; di>100; di++) di++; } */ //DosExitCritSec(); //return ret; threadNum = LSthreads.next_free; LSthreads.state[threadNum] = -1; if(LSthreads.n < threadNum) LSthreads.n = threadNum; debug(0, 2) ("Fs_ClientWork%i: Pipe creating (%i)\n",threadNum,LSthreads.thread_id[threadNum]); // 2 fflush(stdout); ThreadStart++; DosSleep(1); __lxchg(&LSthreads.semaphore, UNLOCKED); do { DosSleep(1); } while(ThreadStart != 3); // if(param) // threadNum = * ((int *)param); DosSleep(1); FreePM_pipe[threadNum] = new NPipe(FREEPM_BASE_PIPE_NAME,SERVER_MODE,FREEPMS_MAX_NUM_THREADS,threadNum); rc = FreePM_pipe[threadNum]->Create(); if(rc == ERROR_TOO_MANY_OPEN_FILES) { rc = OS2SetRelMaxFH(8); rc = FreePM_pipe[threadNum]->Create(); } if(rc) { snprintf(str,256, "Error pipe creating %s rc=%i",FreePM_pipe[threadNum]->name,rc); if(rc == ERROR_INVALID_PARAMETER) strcat(str,"(INVALID PARAMETER)"); else if (rc == ERROR_PIPE_BUSY) strcat(str,"(PIPE_BUSY)"); if (rc == ERROR_PIPE_BUSY) { debug(0, 0) ("WARNING: Fs_ClientWork: %s\n",str); goto ENDTHREAD; } _fatal_common(str); } LSthreads.state[threadNum] = 0; debug(0, 2) ("Fs_ClientWork%i: Pipe create %s %x %x\n",threadNum,FreePM_pipe[threadNum]->name, threadNum ,FreePM_pipe[threadNum]->Hpipe); M_CONNECT: rc = FreePM_pipe[threadNum]->Connect(); if(rc) { debug(0, 0) ("WARNING: Error connecting pipe %s: %s\n",FreePM_pipe[threadNum]->name,xstdio_strerror()); goto ENDTHREAD; } debug(0, 2) ("Fs_ClientWork%i: Connecting pipe: %s Ok\n",threadNum,FreePM_pipe[threadNum]->name); LSthreads.state[threadNum] = 1; rc = FreePM_pipe[threadNum]->HandShake(); if(rc) { debug(0, 0) ("WARNING: Error HandShake pipe %s: %s\n",FreePM_pipe[threadNum]->name,xstdio_strerror()); rc = DosDisConnectNPipe(FreePM_pipe[threadNum]->Hpipe); goto M_CONNECT; } debug(0, 2) ("Fs_ClientWork%i: HandShake pipe: %s Ok\n",threadNum,FreePM_pipe[threadNum]->name); /***********/ for(i = 0; i < FREEPMS_MAX_NUM_THREADS; i++) { // debug(0, 0) ("(%i %i)",i,LSthreads.thread_id[i]); if(LSthreads.thread_id[i] == -1) { break; } } idd = LSthreads.next_free; // debug(0, 0) ("idd=%i",idd); ThreadStart = 1; LSthreads.state[threadNum] = 2; id = _beginthread(Fs_ClientWork,NULL, THREAD_STACK_SIZE,&idd); do { DosSleep(1); } while(ThreadStart == 1); while(__lxchg(&LSthreads.semaphore, LOCKED)) DosSleep(1); LSthreads.Nclients++; // число живых клиентов LSthreads.working = 1; // =0 на старте, =1 после появления первого живого клиента (защелка) LSthreads.num++; LSthreads.thread_id[LSthreads.next_free] = id; for(i = 0; i < FREEPMS_MAX_NUM_THREADS; i++) { // l = (i + LSthreads.next_free)%MAX_NUM_THREADS; // debug(0, 0) ("[%i %i]",i,LSthreads.thread_id[i]); if(LSthreads.thread_id[i] == -1) { LSthreads.next_free = i; break; } } ThreadStart = 3; __lxchg(&LSthreads.semaphore, UNLOCKED); DosSleep(1); debug(0, 2)("Fs_ClientWork%i: Pipe working %s\n", threadNum, FreePM_pipe[threadNum]->name); /*****************/ do { LSthreads.state[threadNum] = 3; rc = _F_RecvCmdFromClient((void *)FreePM_pipe[threadNum], &ncmd,&data); if(rc) { if(rc == -1) { rc = FreePM_pipe[threadNum]->QueryState(); if(rc == ERROR_BAD_PIPE || rc == ERROR_PIPE_NOT_CONNECTED) break; // клиент подох ?? } debug(0, 9)("WARNING: Fs_ClientWork: RecvCmdFromClient error %x %s\n", rc, xstdio_strerror()); goto ENDTHREAD; } LSthreads.state[threadNum] = 1; LSthreads.state[threadNum] = 4; debug(0, 9)("Fs_ClientWork: Get ncmd %x %x\n",ncmd, data); // handle the command handler((void *)FreePM_pipe[threadNum], ncmd, data, threadNum); } while(ncmd); /*****************/ ENDTHREAD: LSthreads.state[threadNum]= 5; debug(0, 2) ("Fs_ClientWork%i: Pipe Closing %s %x %x\n",threadNum,FreePM_pipe[threadNum]->name, threadNum ,FreePM_pipe[threadNum]->Hpipe); // DosSleep(3000); // rc = DosDisConnectNPipe(FreePM_pipe[threadNum].Hpipe); // rc += DosClose(FreePM_pipe[threadNum].Hpipe); rc = FreePM_pipe[threadNum]->Close(); debug(0, 2) ("Fs_ClientWork%i: Pipe Close %s, Thread %i, ThId=%i, rc=%x\n", threadNum,FreePM_pipe[threadNum]->name, LSthreads.thread_id[threadNum],rc); fflush(stdout); //todo: call timeout_handler to kill windows with closed habs while(__lxchg(&LSthreads.semaphore, LOCKED)) DosSleep(1); // sgLogError("End thread %i\n",threadNum); LSthreads.num--; LSthreads.thread_id[threadNum] = -1; LSthreads.state[threadNum] = -1; if(LSthreads.thread_id[LSthreads.next_free] != -1 || LSthreads.next_free > threadNum) LSthreads.next_free = threadNum; if(LSthreads.n < threadNum) LSthreads.n = threadNum; for(i=0; i < FREEPMS_MAX_NUM_THREADS; i++) { // l = (i + LSthreads.next_free)%MAX_NUM_THREADS; // debug(0, 0) ("[%i %i]",i,LSthreads.thread_id[i]); if(LSthreads.thread_id[i] == -1) { LSthreads.next_free = i; break; } } LSthreads.Nclients--; // число живых клиентов __lxchg(&LSthreads.semaphore, UNLOCKED); DosSleep(1); }
_Inline VOID heapLock(VOID) { while ( __lxchg(&isem, HEAP_LOCK) ) DosSleep(1); }