/* застрелиться при ошибках */ extern "C" APIRET APIENTRY _F_SendGenCmdDataToServer(void *recvobj, int cmd, int par, void *data, int datalen) { int rc,len,retcode; M: rc = _F_SendCmdToServer(recvobj, cmd, par); if(rc) { debug(1, 0)("WARNING:"__FUNCTION__":SendCmdToServer Error: %s\n",GetOS2ErrorMessage(rc)); _fatal_common("SendCmdToServer Error\n"); } rc = _F_SendDataToServer(recvobj, data, datalen * sizeof(int)); if(rc) { if(rc == ERROR_BROKEN_PIPE) { debug(1, 1)("WARNING:"__FUNCTION__":SendDataToServer return Broken Pipe, try to reconnect...\n"); goto M;/* attempt to reconnect till timeout */ } debug(1, 0)("WARNING:"__FUNCTION__":SendDataToServer Error: %s\n",GetOS2ErrorMessage(rc)); _fatal_common("SendCmdToServer Error\n"); } rc = _F_RecvDataFromServer(recvobj, &retcode, &len, sizeof(int)); if(rc) { if(rc == ERROR_BROKEN_PIPE) { debug(1, 1)("WARNING:"__FUNCTION__":SendDataToServer return Broken Pipe, try to reconnect...\n"); goto M;/* attempt to reconnect till timeout */ } debug(1, 0)("WARNING:"__FUNCTION__":RecvDataFromServer Error: %s\n",GetOS2ErrorMessage(rc)); _fatal_common("RecvDataFromServer Error\n"); } debug(1, 3)( __FUNCTION__ " retcode =%x\n",retcode); return retcode; }
/* застрелиться при ошибках */ extern "C" APIRET APIENTRY _F_SendGenCmdToServer(void *recvobj, int cmd, int par) { int rc,len,retcode; rc = _F_SendCmdToServer(recvobj, cmd, par); if(rc) { debug(1, 0)("WARNING:"__FUNCTION__":SendCmdToServer Error: %s\n",GetOS2ErrorMessage(rc)); _fatal_common("SendCmdToServer Error\n"); } rc = _F_RecvDataFromServer(recvobj, &retcode, &len, sizeof(int)); if(rc) { debug(1, 0)("WARNING:"__FUNCTION__":RecvDataFromServer Error: %s\n",GetOS2ErrorMessage(rc)); _fatal_common("RecvDataFromServer Error\n"); } debug(1, 3)( __FUNCTION__ "(cmd=%x, par=%x) ret =%x\n",cmd, par, retcode); return retcode; }
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); }
// the callback in the server called by a communication backend // on each comm. protocol command void handler (ULONG obj, int ncmd, int data, int threadNum) { int rc, l, len; char buf[256]; switch(ncmd) { case F_CMD_GET_IHAB: { int iHAB = 1, inf[2]; static int iClientId = 1; debug(0, 2)("Fs_ClientWork: F_CMD_GET_IHAB not yet full implemented\n"); iClientId++; iHAB = session.hab_list.Add(iClientId ,threadNum); inf[0] = iHAB; inf[1] = iClientId; rc= F_SendDataToClient(obj, inf , sizeof(inf)); } break; case F_CMD_CLIENT_EXIT: //todo: clear ihab = data debug(0, 2) ("Fs_ClientWork: F_CMD_CLIENT_EXIT %x ; not yet implemented\n", data); break; case F_CMD_WINPOSTMSG: { SQMSG sqmsg; int rc1,ihabto; rc = F_RecvDataFromClient(obj, &sqmsg, &l, sizeof(SQMSG)); debug(0, 2) ("Fs_ClientWork: F_CMD_WINPOSTMSG get %i bytes\n",l); if(rc == 0 && l == sizeof(SQMSG)) { rc1 = _WndList.QueryHab(sqmsg.qmsg.hwnd, ihabto); if(rc1 == 1) { sqmsg.ihto = ihabto; rc = session.hab_list.Queue.Add(&sqmsg); } } } break; case F_CMD_WINSENDMSG: { SQMSG sqmsg; int rc1,ihabto; rc = F_RecvDataFromClient(obj, &sqmsg, &l, sizeof(SQMSG)); debug(0, 2) ("Fs_ClientWork: F_CMD_WINPOSTMSG get %i bytes\n",l); if(rc == 0 && l == sizeof(SQMSG)) { rc1 = _WndList.QueryHab(sqmsg.qmsg.hwnd, ihabto); if(rc1 == 1) { sqmsg.ihto = ihabto; //todo: it is sendmsg == postmsg implementation //it seems that we must wait in client via call to CMD_WINQUERYPOSTED or smth like it rc = session.hab_list.Queue.Add(&sqmsg); } } } break; case F_CMD_WINQUERY_MSG: /* Query messages for ihab = data */ { int nmsg=0; int ihabto; ihabto = data; nmsg = session.hab_list.Queue.QueryNmsg(ihabto); if (nmsg) debug(0, 2) ("Fs_ClientWork: F_CMD_WINQUERY_MSG, nmsg=%i\n",nmsg); rc = F_SendDataToClient(obj, &nmsg , sizeof(int)); } break; case F_CMD_WINGET_MSG: /* Get message for ihab = data */ { SQMSG sqmsg; int rc, ihabto; int nmsg=0; ihabto = data; rc = session.hab_list.Queue.GetForIhab(&sqmsg, ihabto); if (rc == 0) nmsg = 1; if (nmsg == 1) debug(0, 2) ("Fs_ClientWork: F_CMD_WINGET_MSG for %i, msg=%x\n", ihabto, sqmsg.qmsg.msg); else debug(0, 2) ("Fs_ClientWork: F_CMD_WINGET_MSG, No msg for %i\n", ihabto); rc = F_SendDataToClient(obj, &nmsg , sizeof(int)); if(nmsg) rc = F_SendDataToClient(obj, &sqmsg.qmsg , sizeof(QMSG)); } break; case F_CMD_WINCREATE_HWND: { HWND hwnd; int iHab; iHab = data; hwnd = _WndList.Add(iHab); //todo: set _WndList with thread info and cleanup at thread(client exit) end rc= F_SendDataToClient(obj, &hwnd , sizeof(HWND)); } break; case F_CMD_WINSET_PARENT_HWND: { HWND hwnd, hwndParent; hwnd = data; rc = F_RecvDataFromClient(obj, (void *)&hwndParent, &len, sizeof(HWND)); rc = _WndList.SetParent(hwnd, hwndParent); } break; case F_CMD_GET_HPS: { HWND hwnd; HPS hps; hwnd = data; hps = _WndList.GetHPS(hwnd); rc= F_SendDataToClient(obj, &hps, sizeof(HPS)); } break; case F_CMD_RELEASE_HPS: { HPS hps; int rc1; hps = data; rc1 = _WndList.ReleaseHPS(hps); rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_WIN_SET_WND_SIZE: { HWND hwnd = data; int par[2],rc1; rc = F_RecvDataFromClient(obj, (void *)&par[0], &len, sizeof(int)*2); rc1 = 0; //todo rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_WIN_SET_WND_POS: { HWND hwnd = data; int par[2],rc1; rc = F_RecvDataFromClient(obj, (void *)&par[0], &len, sizeof(int)*2); rc1 = 0; //todo rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_WIN_GET_WND_SWP: { HWND hwnd = data; SWP swp; //todo rc= F_SendDataToClient(obj, &swp, sizeof(SWP)); } break; case F_CMD_WIN_SHOW: { HWND hwnd = data; int par,rc1; rc = F_RecvDataFromClient(obj, (void *)&par, &len, sizeof(int)); rc1 = 0; //todo rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_GPI_SET_COLOR: { HPS hps; int color, len, rc1=FALSE; hps = data; rc = F_RecvDataFromClient(obj, (void *)&color, &len, sizeof(int)); debug(0, 0) ("F_CMD_GPI_SET_COLOR: get hps=%x, color=%x, len=%i\n",hps,color,len); if(hps >= 0 && hps < _WndList.numPS) { if(_WndList.pPS[hps].used) /* rc1 = F_GpiSetColor(&_WndList.pPS[hps], color); */ rc1 = F_PS_GpiSetColor(&_WndList.pPS[hps], color); } rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_GPI_MOVE: { HPS hps; int rc1=FALSE; POINTL Point; hps = data; rc = F_RecvDataFromClient(obj, (void *)&Point, &len, sizeof(POINTL)); debug(0, 0) ("F_CMD_GPI_MOVE: get hps=%x,len=%i\n",hps,len); if(hps >= 0 && hps < _WndList.numPS) { if(_WndList.pPS[hps].used) rc1 = F_PS_GpiMove(&_WndList.pPS[hps], &Point); } rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_GPI_LINE: { HPS hps; int rc1=FALSE; POINTL Point; hps = data; rc = F_RecvDataFromClient(obj, (void *)&Point, &len, sizeof(POINTL)); if(hps >= 0 && hps < _WndList.numPS) { if(_WndList.pPS[hps].used) rc1 = F_PS_GpiLine(&_WndList.pPS[hps], &Point); } rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_GPI_DRAW_LINE: //TODO break; case F_CMD_GPI_DRAW_RECT: //TODO break; case F_CMD_DB_PRINT: { F_RecvDataFromClient(obj, (char *)buf, &len, sizeof(buf)); _db_print(buf); } break; case F_CMD_FATAL_COMMON: F_RecvDataFromClient(obj, (char *)buf, &len, sizeof(buf)); _fatal_common(buf); break; #define POKA 0 #if POKA case 1: debug(0, 2) ("Fs_ClientWork: Get ncmd %x %x\n", ncmd, data); rc=F_SendCmdToServer(obj, ncmd, data); switch(data) { case S_SHUTDOWN: // squid_signal(SIGTERM, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART); // debug(0, 0) ("squid_signal:\n"); DosSleep(100); rc = raise(SIGTERM); // debug(0, 0) ("raise: rc =%x %s\n",rc,xstdio_strerror()); break; case S_RECONFIGURE: // do_reconfigure = 1; break; case S_ROTATE: // do_rotate = 1; break; case S_DEBUG: break; case S_KILL: debug(1, 1) ("Preparing for killing\n"); // do_shutdown++; // SquidShutdown(NULL); break; } ncmd = 0; break; #endif //POKA default: debug(0, 2) ("Fs_ClientWork:WARNING: Unimplemented cmd %x\n", ncmd); ncmd = 0; break; } //endof switch(ncmd) }