/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include #ifdef OS2 #include #include #endif #ifdef DXD_HAS_WINSOCKETS #include #endif #include "../base/UIConfig.h" #include "../base/defines.h" #include "dxlP.h" #ifdef OS2 VOID _Optlink PMCheckInputThread(void *Voidconn); #else void PMCheckInputThread(void *Voidconn); #endif static void _dxl_InputHandler(void *clientData) { DXLConnection *conn = (DXLConnection *)clientData; DXLHandlePendingMessages(conn); } /* FIXME: arrange for _dxl_InputHandler to be called when input available * on the connection, or deliver a message to the main loop that must * recognize this message and call DXLHandlePendingMessages(). */ #ifdef OS2 DXLError DXLInitializePMMainLoop(HWND PMAppWindow, DXLConnection *conn) { static TID tidPMCheckInputThread; APIRET rc; conn->PMAppWindow = PMAppWindow; rc = DosCreateEventSem(NULL,&conn->PMHandlerSemaphore,DC_SEM_SHARED,0); tidPMCheckInputThread = _beginthread(PMCheckInputThread,NULL,4096,conn); return TRUE; } #else #ifdef DXD_WIN DXLError DXLInitializePMMainLoop(HWND PMAppWindow, DXLConnection *conn) /* ajay */ { int rc; conn->PMAppWindow = PMAppWindow; conn->PMHandlerSemaphore = CreateEvent(NULL, 0, 1000, NULL); rc = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) PMCheckInputThread, (LPVOID) NULL, 0, (LPVOID) conn); return TRUE; } #else DXLError DXLInitializePMMainLoop() { return FALSE; } #endif #endif /* ******************************************************************* */ /* Routines for PMCheckInput thread */ /* ******************************************************************* */ #ifdef OS2 VOID _Optlink PMCheckInputThread(void *Voidconn) { DXLConnection *conn; int i,j; HAB habt; HMQ hmqt; QMSG qmsgt; int rc; ULONG SemPostCount; _fpreset(); habt=WinInitialize(0); hmqt=WinCreateMsgQueue(habt,0); conn = (DXLConnection *)Voidconn; for (;;) { rc = select(&conn->fd,1,0,0,-1); if (rc!=1) { WinDestroyMsgQueue(hmqt); WinTerminate(habt); DosExit(0,0); } rc = WinPostMsg(conn->PMAppWindow,WM_DXL_HANDLE_PENDING_MESSAGE,(ULONG)conn,0L); rc = DosWaitEventSem(conn->PMHandlerSemaphore,-1); rc = DosResetEventSem(conn->PMHandlerSemaphore, &SemPostCount); } } #else #ifdef DXD_HAS_WINSOCKETS void PMCheckInputThread(void *Voidconn) { int rc; fd_set fds; DXLConnection *conn; struct timeval tv; _fpreset(); conn = (DXLConnection *)Voidconn; tv.tv_usec = 1; tv.tv_sec = 0; FD_ZERO(&fds); FD_SET(conn->fd, &fds); for(;;) { rc = select(conn->fd,&fds,0,0,&tv); if (rc!=1) { PostQuitMessage(WM_QUIT); exit(0); } rc = PostMessage(conn->PMAppWindow, WM_DXL_HANDLE_PENDING_MESSAGE, (WPARAM) conn, NULL); rc = WaitForSingleObject(conn->PMHandlerSemaphore, INFINITE); rc = ResetEvent(conn->PMHandlerSemaphore); } } #else void PMCheckInputThread(void *Voidconn) { } #endif #endif /*****************************************************************************\ The following are patches to allow IBM OS/2 sockets to send messages that cross a segment boundary (which *could* happen for any message longer than 4 bytes). This is necessary because the OS/2 socket calls are still 16-bit code. When the library goes 32-bit, this should no longer be needed. suits 6/94. \*****************************************************************************/ /* This code is written for non-Berkeley select calls. Thus must override */ /* the select macro if it has been defined. */ #ifdef select #undef select #endif #ifdef BSD_SELECT #undef BSD_SELECT #endif int _dxl_os2_send(int s, char *ExternalBuffer, int TotalBytesToSend, int Flags) { #ifdef OS2 #define MAX_BYTES_PER_SEND 32767 #define UX_SEND_SEG_SIZE 65536 #define UX_SEND_TIMEOUT 20000 int BytesToSend; int BuffPtr; int BytesRemaining; if (select((int *)&s,0,1,0,UX_SEND_TIMEOUT)<=0) return -1; BytesRemaining = TotalBytesToSend; BuffPtr = 0; while (BytesRemaining>0) { BytesToSend = (unsigned short)(-(unsigned long)&ExternalBuffer[BuffPtr]); if (BytesToSend == 0) BytesToSend = UX_SEND_SEG_SIZE; if (BytesToSend>BytesRemaining) BytesToSend = BytesRemaining; if (BytesToSend > MAX_BYTES_PER_SEND) BytesToSend = MAX_BYTES_PER_SEND; if (send(s, &ExternalBuffer[BuffPtr], BytesToSend, Flags)<1) { if (sock_errno()!=SOCEWOULDBLOCK) return -1; if (select((int *)&s,0,1,0,5000)<=0) return -1; } else { BuffPtr += BytesToSend; BytesRemaining -= BytesToSend; } } return (int) BuffPtr; #endif #ifdef DXD_HAS_WINSOCKETS int BuffPtr; BuffPtr = send(s, ExternalBuffer, TotalBytesToSend, Flags); return BuffPtr; #endif return (int) -1; } int _dxl_os2_recv(int s, char *ExternalBuffer, int BuffSize, int Flags) { #ifdef OS2 #define MAX_BYTES_PER_RECV 32767 #define UX_RECV_SEG_SIZE 65536 #define UX_RECV_TIMEOUT 20000 int BytesToReceive; int BuffPtr; int BytesRemaining; int NumReceived = -1; if (select((int *)&s,1,0,0,UX_RECV_TIMEOUT)<=0) return -1; BytesRemaining = BuffSize; BuffPtr = 0; while (NumReceived != 0 && BytesRemaining != 0) { BytesToReceive = (unsigned short)(-(unsigned long)&ExternalBuffer[BuffPtr]); if (BytesToReceive == 0) BytesToReceive = UX_RECV_SEG_SIZE; if (BytesToReceive>BytesRemaining) BytesToReceive = BytesRemaining; if (BytesToReceive>MAX_BYTES_PER_RECV) BytesToReceive = MAX_BYTES_PER_RECV; if ((NumReceived = recv(s, &ExternalBuffer[BuffPtr], BytesToReceive, Flags))<0) { if (sock_errno()!=SOCEWOULDBLOCK) return -1; else return (int) BuffPtr; } BuffPtr += NumReceived; BytesRemaining -= NumReceived; } return (int) BuffPtr; #endif #ifdef DXD_HAS_WINSOCKETS int BuffPtr; BuffPtr = recv(s, ExternalBuffer, BuffSize, Flags); return (int) BuffPtr; #endif return (int) -1; }