aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c')
-rw-r--r--nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c497
1 files changed, 0 insertions, 497 deletions
diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c
deleted file mode 100644
index 395104242..000000000
--- a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/* $XConsortium: os2_select.c /main/6 1996/10/27 11:48:55 kaleb $ */
-
-
-
-
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c,v 3.9 2003/03/25 04:18:24 dawes Exp $ */
-
-/*
- * (c) Copyright 1996 by Sebastien Marineau
- * <marineau@genie.uottawa.ca>
- * Modified 1999 by Holger.Veit@gmd.de
- * Modified 2004 by Frank Giessler
- * <giessler@biomag.uni-jena.de>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Sebastien Marineau shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from Sebastien Marineau.
- *
- */
-
-/* os2_select.c: reimplementation of the xserver select(), optimized for speed */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <memory.h>
-#include <io.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/errno.h>
-#include <emx/io.h>
-
-#define I_NEED_OS2_H
-#define INCL_DOSSEMAPHORES
-#define INCL_DOSPROFILE
-#define INCL_DOSPROCESS
-#define INCL_DOSFILEMGR
-#define INCL_DOSMISC
-#define INCL_DOSMODULEMGR
-
-
-#include <X11/Xpoll.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-
-#include "os2_select.h"
-
-int os2MouseQueueQuery();
-int os2KbdQueueQuery();
-void os2RecoverFromPopup();
-void os2CheckPopupPending();
-void os2SocketMonitorThread();
-extern BOOL os2PopupErrorPending;
-
-extern HEV hKbdSem;
-extern HEV hMouseSem;
-extern HEV hevServerHasFocus;
-HEV hPipeSem;
-HEV hSocketSem;
-HEV hActivateSocketSem;
-HEV hSwitchToSem;
-static HMUX hSelectWait;
-SEMRECORD SelectMuxRecord[5];
-HMODULE hmod_so32dll;
-static struct select_data sd;
-
-static int (*os2_tcp_select)(int *,int,int,int,long);
-static int (*os2_so_cancel)(int);
-static int (*os2_sock_errno)();
-int os2_set_error(ULONG);
-extern int _files[];
-
-
-
-/* This is a new implementation of select, for improved efficiency */
-/* This function performs select() on sockets */
-/* but uses OS/2 internal fncts to check mouse */
-/* and keyboard. S. Marineau, 27/4/96 */
-
-/* This is still VERY messy */
-
-/* A few note on optimizations: this select has been tuned for maximum
-* performance, and thus has a different approach than a general-purpose
-* select. It should not be used in another app without modifications. Further,
-* it may need modifications if the Xserver os code is modified
-* Assumptions: this is never called with anything in exceptfds. This is
-* silently ignored. Further, if any pipes are specified in the write mask, it is
-* because they have just been stuffed full by the xserver. There is not much
-* in immediately returning with those bits set. Instead, we block on the
-* semaphore for at least one tick, which will let the client at least start
-* to flush the pipe. */
-
-int os2PseudoSelect(nfds,readfds,writefds,exceptfds,timeout)
- int nfds;
- fd_set *readfds,*writefds,*exceptfds;
- struct timeval *timeout;
-{
-
- static BOOL FirstTime=TRUE;
-
- int n,ns,np;
- int ready_handles;
- ULONG timeout_ms;
- BOOL any_ready;
- ULONG semKey,postCount;
- APIRET rc;
- char faildata[16];
- static int Socket_Tid;
-
- sd.have_read=FALSE; sd.have_write=FALSE;
- sd.socket_nread=0; sd.socket_nwrite=0; sd.socket_ntotal=0;
- sd.max_fds=31; ready_handles=0; any_ready=FALSE;
- sd.pipe_ntotal=0; sd.pipe_have_write=FALSE;
-
- /* Stuff we have to do the first time this is called to set up various parameters */
-
- if (FirstTime) {
- /* First load the so32dll.dll module and get a pointer to the SELECT fn */
-
- if ((rc=DosLoadModule(faildata,sizeof(faildata),"SO32DLL",&hmod_so32dll))!=0) {
- FatalError("Could not load module so32dll.dll, rc = %d. Error note %s\n",rc,faildata);
- }
- if ((rc = DosQueryProcAddr(hmod_so32dll, 0, "SELECT", (PPFN)&os2_tcp_select))!=0) {
- FatalError("Could not query address of SELECT, rc = %d.\n",rc);
- }
- if ((rc = DosQueryProcAddr(hmod_so32dll, 0, "SO_CANCEL", (PPFN)&os2_so_cancel))!=0) {
- FatalError("Could not query address of SO_CANCEL, rc = %d.\n",rc);
- }
- if ((rc = DosQueryProcAddr(hmod_so32dll, 0, "SOCK_ERRNO", (PPFN)&os2_sock_errno))!=0) {
- FatalError("Could not query address of SOCK_ERRNO, rc = %d.\n",rc);
- }
-
- /* Call these a first time to set the semaphore */
- xf86OsMouseEvents();
- xf86KbdEvents();
-
- DosCreateEventSem(NULL, &hSocketSem,DC_SEM_SHARED,FALSE);
- DosResetEventSem(hSocketSem,&postCount);
-
- DosCreateEventSem(NULL, &hActivateSocketSem, DC_SEM_SHARED, FALSE);
- DosResetEventSem(hActivateSocketSem, &postCount);
-
- DosCreateEventSem(NULL, &hSwitchToSem, DC_SEM_SHARED, FALSE);
- DosResetEventSem(hSwitchToSem, &postCount);
-
- Socket_Tid = _beginthread(os2SocketMonitorThread, NULL, 0x2000,(void *) NULL);
- xf86Msg(X_INFO,
- "Started Socket monitor thread, TID=%d\n",Socket_Tid);
-
- SelectMuxRecord[0].hsemCur = (HSEM)hMouseSem;
- SelectMuxRecord[0].ulUser = MOUSE_SEM_KEY;
- SelectMuxRecord[1].hsemCur = (HSEM)hKbdSem;
- SelectMuxRecord[1].ulUser = KBD_SEM_KEY;
- SelectMuxRecord[2].hsemCur = (HSEM)hPipeSem;
- SelectMuxRecord[2].ulUser = PIPE_SEM_KEY;
- SelectMuxRecord[3].hsemCur = (HSEM)hSocketSem;
- SelectMuxRecord[3].ulUser = SOCKET_SEM_KEY;
- SelectMuxRecord[4].hsemCur = (HSEM)hSwitchToSem;
- SelectMuxRecord[4].ulUser = SWITCHTO_SEM_KEY;
-
- rc = DosCreateMuxWaitSem(NULL, &hSelectWait, 5, SelectMuxRecord,
- DC_SEM_SHARED | DCMW_WAIT_ANY);
- if (rc) {
- xf86Msg(X_ERROR,"Could not create MuxWait semaphore, rc=%d\n",rc);
- }
- FirstTime = FALSE;
- }
-
- rc = DosResetEventSem(hActivateSocketSem, &postCount);
- /* Set up the time delay structs */
-
- if (timeout!=NULL) {
- timeout_ms=timeout->tv_sec*1000+timeout->tv_usec/1000;
- } else {
- timeout_ms=1000000; /* This should be large enough... */
- }
-
- /* Zero our local fd_masks */
- {FD_ZERO(&sd.read_copy);}
- {FD_ZERO(&sd.write_copy);}
-
- /* Copy the masks for later use */
- if (readfds!=NULL) { XFD_COPYSET(readfds,&sd.read_copy); sd.have_read=TRUE; }
- if (writefds!=NULL) {XFD_COPYSET(writefds,&sd.write_copy); sd.have_write=TRUE; }
-
- /* And zero the original masks */
- if (sd.have_read){ FD_ZERO(readfds); }
- if (sd.have_write) {FD_ZERO(writefds); }
- if (exceptfds != NULL) {FD_ZERO(exceptfds); }
-
- /* Now we parse the fd_sets passed to select and separate pipe/sockets */
- n = os2_parse_select(&sd,nfds);
-
- /* Now check if we have sockets ready! */
-
- if (sd.socket_ntotal > 0) {
- ns = os2_poll_sockets(&sd,readfds,writefds);
- if (ns>0) {
- ready_handles+=ns;
- any_ready = TRUE;
- } else if (ns == -1) {
- return(-1);
- }
- }
-
- /* And pipes */
-
- if (sd.pipe_ntotal > 0) {
- np = os2_check_pipes(&sd,readfds,writefds);
- if (np > 0) {
- ready_handles+=np;
- any_ready = TRUE;
- } else if (np == -1) {
- return(-1);
- }
- }
-
- /* And finally poll input devices */
- if(!os2MouseQueueQuery() || !os2KbdQueueQuery() ) any_ready = TRUE;
-
- if (xf86Info.vtRequestsPending) any_ready=TRUE;
-
- if (os2PopupErrorPending)
- os2RecoverFromPopup();
-
- if (!any_ready && timeout_ms) {
- DosResetEventSem(hSocketSem,&postCount);
-
- /* Activate the socket thread */
- if (sd.socket_ntotal>0) {
- rc = DosPostEventSem(hActivateSocketSem);
- }
-
- rc = DosWaitMuxWaitSem(hSelectWait, timeout_ms, &semKey);
-
- /* If our socket monitor thread is still blocked in os2_tcp_select()
- * we have to wake it up by calling os2_so_cancel().
- * After that, call os2_tcp_select() once more to get rid of
- * error SOCEINTR (10004)
- */
- if (sd.socket_ntotal>0) {
- rc = DosQueryEventSem(hSocketSem, &postCount);
-
- if (postCount == 0) { /* os2_select still blocked */
- int i,f,g;
- struct select_data *sd_ptr=&sd;
-
- if (sd.socket_nread > 0) {
- for (i=0; i<sd.socket_nread; i++) {
- f = g = sd_ptr->tcp_select_mask[i];
- os2_so_cancel(f);
- os2_tcp_select(&g, 1, 0, 0, 0); /* get rid of error 10004 */
- }
- }
- if (sd.socket_nwrite > 0) {
- for (i=sd.socket_nread;
- i<sd.socket_nread+sd.socket_nwrite;
- i++) {
- f = g = sd_ptr->tcp_select_mask[i];
- os2_so_cancel(f);
- os2_tcp_select(&g, 0, 1, 0, 0); /* get rid of error 10004 */
- }
- }
- } else { /* not blocked, something must be ready -> get it */
- ns = os2_poll_sockets(&sd,readfds,writefds);
- if (ns>0) {
- ready_handles+=ns;
- } else if (ns == -1) {
- return(-1);
- }
- }
- }
- if (sd.pipe_ntotal > 0) {
- rc = DosQueryEventSem(hPipeSem,&postCount);
- if (postCount > 0) {
- np = os2_check_pipes(&sd,readfds,writefds);
- if (np > 0) {
- ready_handles+=np;
- } else if (np == -1) {
- return(-1);
- }
- }
- }
- }
- /* The polling of sockets/pipe automatically set the proper bits */
- return (ready_handles);
-}
-
-
-int os2_parse_select(sd,nfds)
- struct select_data *sd;
- int nfds;
-{
- int i;
- /* First we determine up to which descriptor we need to check. */
- /* No need to check up to 256 if we don't have to (and usually we dont...)*/
- /* Note: stuff here is hardcoded for fd_sets which are int[8] as in EMX!!! */
-
- if (nfds > sd->max_fds) {
- for (i=0;i<((FD_SETSIZE+31)/32);i++) {
- if (sd->read_copy.fds_bits[i] ||
- sd->write_copy.fds_bits[i])
- sd->max_fds=(i*32) +32;
- }
- } else { sd->max_fds = nfds; }
-
- /* Check if this is greater than specified in select() call */
- if(sd->max_fds > nfds) sd->max_fds = nfds;
-
- if (sd->have_read) {
- for (i = 0; i < sd->max_fds; ++i) {
- if (FD_ISSET (i, &sd->read_copy)) {
- if(_files[i] & F_SOCKET) {
- sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
- sd->tcp_emx_handles[sd->socket_ntotal]=i;
- sd->socket_ntotal++; sd->socket_nread++;
- } else if (_files[i] & F_PIPE) {
- sd -> pipe_ntotal++;
- }
- }
- }
- }
- if (sd->have_write) {
- for (i = 0; i < sd->max_fds; ++i) {
- if (FD_ISSET (i, &sd->write_copy)) {
- if (_files[i] & F_SOCKET) {
- sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
- sd->tcp_emx_handles[sd->socket_ntotal]=i;
- sd->socket_ntotal++; sd->socket_nwrite++;
- } else if (_files[i] & F_PIPE) {
- sd -> pipe_ntotal++;
- sd -> pipe_have_write=TRUE;
- }
- }
- }
- }
- return(sd->socket_ntotal);
-}
-
-
-int os2_poll_sockets(sd,readfds,writefds)
- struct select_data *sd;
- fd_set *readfds,*writefds;
-{
- int e,i;
- int j,n;
-
- memcpy(sd->tcp_select_copy,sd->tcp_select_mask,
- sd->socket_ntotal*sizeof(int));
-
- e = os2_tcp_select(sd->tcp_select_copy,sd->socket_nread,
- sd->socket_nwrite, 0, 0);
-
- if (e == 0) return(e);
-
- /* We have something ready? */
- if (e>0) {
- j = 0; n = 0;
- for (i = 0; i < sd->socket_nread; ++i, ++j)
- if (sd->tcp_select_copy[j] != -1) {
- FD_SET (sd->tcp_emx_handles[j], readfds);
- n ++;
- }
- for (i = 0; i < sd->socket_nwrite; ++i, ++j)
- if (sd->tcp_select_copy[j] != -1) {
- FD_SET (sd->tcp_emx_handles[j], writefds);
- n ++;
- }
- errno = 0;
-
- return n;
- }
- if (e<0) {
- /*Error -- TODO */
- xf86Msg(X_ERROR,"Error in server select! sock_errno = %d\n",os2_sock_errno());
- errno = EBADF;
- return (-1);
- }
-}
-
-/* Check to see if anything is ready on pipes */
-
-int os2_check_pipes(sd,readfds,writefds)
- struct select_data *sd;
- fd_set *readfds,*writefds;
-{
- int i,e;
- ULONG ulPostCount;
- PIPESEMSTATE pipeSemState[128];
- APIRET rc;
-
- e = 0;
- rc = DosResetEventSem(hPipeSem,&ulPostCount);
- rc = DosQueryNPipeSemState((HSEM) hPipeSem, (PPIPESEMSTATE)&pipeSemState,
- sizeof(pipeSemState));
- if(rc) xf86Msg(X_ERROR,"SELECT: rc from QueryNPipeSem: %d\n",rc);
- i=0;
- while (pipeSemState[i].fStatus != 0) {
-/* xf86Msg(X_INFO,"SELECT: sem entry, stat=%d, flag=%d, key=%d,avail=%d\n",
- pipeSemState[i].fStatus,pipeSemState[i].fFlag,pipeSemState[i].usKey,
- pipeSemState[i].usAvail); */
- if ((pipeSemState[i].fStatus == 1) &&
- (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy))) {
- FD_SET(pipeSemState[i].usKey,readfds);
- e++;
- } else if ((pipeSemState[i].fStatus == 2) &&
- (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy))) {
- FD_SET(pipeSemState[i].usKey,writefds);
- e++;
- } else if ((pipeSemState[i].fStatus == 3) &&
- ((FD_ISSET(pipeSemState[i].usKey,&sd->read_copy)) ||
- (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy)) )) {
- errno = EBADF;
- /* xf86Msg(X_ERROR,"Pipe has closed down, fd=%d\n",pipeSemState[i].usKey); */
- return (-1);
- }
- i++;
- } /* endwhile */
-
- errno = 0;
- return(e);
-}
-
-
-void os2SocketMonitorThread(void *arg)
-{
- struct select_data *sd_ptr = &sd;
- ULONG ulPostCount;
- int e,rc;
-
- /* Make thread time critical */
- DosSetPriority(2L,3L,0L,0L);
-
- while (1) {
- rc = DosWaitEventSem(hActivateSocketSem, SEM_INDEFINITE_WAIT);
- if (rc != 0 )
- xf86Msg(X_ERROR,"Socket monitor: DosWaitEventSem(hActivateSocketSem..) returned %d\n",rc);
-
- rc = DosResetEventSem(hActivateSocketSem,&ulPostCount);
- if (rc != 0 )
- xf86Msg(X_ERROR,"Socket monitor: DosResetEventSem(&hActivateSocketSem..) returned %d\n",rc);
-
- /* fg300104:
- * The next line shouldn't be here, but the DosPostEventSem()
- * below will return 299 from time to time under heavy load
- */
-/* DosResetEventSem(hSocketSem,&ulPostCount);*/
-
- memcpy(sd_ptr->tcp_select_monitor,sd_ptr->tcp_select_mask,
- sd_ptr->socket_ntotal*sizeof(int));
-
- /* call os2_select(), return only if either something is ready or
- * os2_so_cancel() was called
- */
- e = os2_tcp_select(sd_ptr->tcp_select_monitor, sd_ptr->socket_nread,
- sd_ptr->socket_nwrite, 0, -1);
-
- if (e>0) {
- rc = DosPostEventSem(hSocketSem);
- if (rc != 0 )
- xf86Msg(X_ERROR,"Socket monitor: DosPostEventSem(hSocketSem..) returned %d\n",rc);
- } else if (e<0) {
- rc = os2_sock_errno();
- if (rc != 10004)
- xf86Msg(X_ERROR,"Socket monitor: os2_select: sock_errno = %d\n",rc);
- }
-
- rc = DosQueryEventSem(hevServerHasFocus, &ulPostCount);
-
- /* no need to rush while switched away */
- if ((rc==0) && (ulPostCount==0))
- rc == DosWaitEventSem(hevServerHasFocus,31L);
- }
-}
-