emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 100% CPU on TCP servers (on Windoze).


From: Kim F. Storm
Subject: Re: 100% CPU on TCP servers (on Windoze).
Date: Fri, 14 Jul 2006 15:24:23 +0200
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

"Juanma Barranquero" <address@hidden> writes:

> On 7/14/06, Kim F. Storm <address@hidden> wrote:
>
>> Any idea how to fix that?
>
> You can make it work with the attached patch. Apparently,
> WSAEventSelect is exported from ws2_32.dll but not from wsock32.dll. I
> don't know whether all targets (I mean, all supported Windows
> environments) have or use ws2_32.dll, though.
>
> Unfortunately, with your patch and the attached one, I still see a 50%
> CPU use on the reported example.

Thanks.  Here is something which actually seems to work -- provided
we can use ws2_32.dll:

Index: w32.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32.c,v
retrieving revision 1.103
diff -c -r1.103 w32.c
*** w32.c       14 Jul 2006 09:29:32 -0000      1.103
--- w32.c       14 Jul 2006 13:25:07 -0000
***************
*** 2701,2706 ****
--- 2701,2708 ----
  void (PASCAL *pfn_WSASetLastError) (int iError);
  int (PASCAL *pfn_WSAGetLastError) (void);
  int (PASCAL *pfn_WSAEventSelect) (SOCKET s, HANDLE hEventObject, long 
lNetworkEvents);
+ HANDLE (PASCAL *pfn_WSACreateEvent) (void);
+ int (PASCAL *pfn_WSACloseEvent) (HANDLE hEvent);
  int (PASCAL *pfn_socket) (int af, int type, int protocol);
  int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
  int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int 
namelen);
***************
*** 2770,2776 ****
      = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
                               "SetHandleInformation");
  
!   winsock_lib = LoadLibrary ("wsock32.dll");
  
    if (winsock_lib != NULL)
      {
--- 2772,2778 ----
      = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
                               "SetHandleInformation");
  
!   winsock_lib = LoadLibrary ("Ws2_32.dll");
  
    if (winsock_lib != NULL)
      {
***************
*** 2784,2789 ****
--- 2786,2793 ----
        LOAD_PROC( WSASetLastError );
        LOAD_PROC( WSAGetLastError );
        LOAD_PROC( WSAEventSelect );
+       LOAD_PROC( WSACreateEvent );
+       LOAD_PROC( WSACloseEvent );
        LOAD_PROC( socket );
        LOAD_PROC( bind );
        LOAD_PROC( connect );
***************
*** 3298,3307 ****
        if (rc == SOCKET_ERROR)
        set_errno ();
        else
!       {
!         fd_info[s].flags |= FILE_LISTEN;
!         pfn_WSAEventSelect (SOCK_HANDLE (s), fd_info[s].cp->char_avail, 
FD_ACCEPT);
!       }
        return rc;
      }
    h_errno = ENOTSOCK;
--- 3302,3308 ----
        if (rc == SOCKET_ERROR)
        set_errno ();
        else
!       fd_info[s].flags |= FILE_LISTEN;
        return rc;
      }
    h_errno = ENOTSOCK;
***************
*** 3342,3357 ****
    if (fd_info[s].flags & FILE_LISTEN)
      {
        SOCKET t = pfn_accept (SOCK_HANDLE (s), addr, addrlen);
!       if (t != INVALID_SOCKET)
!       {
!         int fd = socket_to_fd (t);
!         if (fd >= 0)
!           pfn_WSAEventSelect (SOCK_HANDLE (fd), fd_info[fd].cp->char_avail, 
FD_READ | FD_CLOSE);
!         return fd;
!       }
  
!       set_errno ();
!       return -1;
      }
    h_errno = ENOTSOCK;
    return -1;
--- 3343,3357 ----
    if (fd_info[s].flags & FILE_LISTEN)
      {
        SOCKET t = pfn_accept (SOCK_HANDLE (s), addr, addrlen);
!       int fd = -1;
!       if (t == INVALID_SOCKET)
!       set_errno ();
!       else
!       fd = socket_to_fd (t);
  
!       fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED;
!       ResetEvent (fd_info[s].cp->char_avail);
!       return fd;
      }
    h_errno = ENOTSOCK;
    return -1;
***************
*** 3653,3658 ****
--- 3653,3688 ----
    return cp->status;
  }
  
+ int _sys_wait_accept (int fd)
+ {
+   HANDLE hEv;
+   child_process * cp;
+   int rc;
+ 
+   if (fd < 0 || fd >= MAXDESC)
+     return STATUS_READ_ERROR;
+ 
+   cp = fd_info[fd].cp;
+ 
+   if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
+     return STATUS_READ_ERROR;
+ 
+   cp->status = STATUS_READ_FAILED;
+ 
+   hEv = pfn_WSACreateEvent ();
+   rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT);
+   if (rc != SOCKET_ERROR)
+     {
+       rc = WaitForSingleObject (hEv, INFINITE);
+       pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0);
+       pfn_WSACloseEvent (hEv);
+       if (rc == WAIT_OBJECT_0)
+       cp->status = STATUS_READ_SUCCEEDED;
+     }
+ 
+   return cp->status;
+ }
+ 
  int
  sys_read (int fd, char * buffer, unsigned int count)
  {
Index: w32.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32.h,v
retrieving revision 1.20
diff -c -r1.20 w32.h
*** w32.h       14 Jul 2006 09:29:22 -0000      1.20
--- w32.h       14 Jul 2006 13:24:48 -0000
***************
*** 137,142 ****
--- 137,145 ----
  extern void globals_of_w32menu (void);
  extern void syms_of_fontset (void);
  
+ extern int _sys_read_ahead (int fd);
+ extern int _sys_wait_accept (int fd);
+ 
  #endif /* EMACS_W32_H */
  
  /* arch-tag: 02c36b00-312b-4c4d-a1d9-f905c5e968f0
Index: w32proc.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32proc.c,v
retrieving revision 1.66
diff -c -r1.66 w32proc.c
*** w32proc.c   6 Feb 2006 15:23:22 -0000       1.66
--- w32proc.c   14 Jul 2006 13:23:28 -0000
***************
*** 1,6 ****
  /* Process support for GNU Emacs on the Microsoft W32 API.
     Copyright (C) 1992, 1995, 1999, 2000, 2001, 2002, 2003, 2004,
!                  2005, 2006 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
--- 1,6 ----
  /* Process support for GNU Emacs on the Microsoft W32 API.
     Copyright (C) 1992, 1995, 1999, 2000, 2001, 2002, 2003, 2004,
!                2005, 2006 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
***************
*** 280,286 ****
      {
        int rc;
  
!       rc = _sys_read_ahead (cp->fd);
  
        /* The name char_avail is a misnomer - it really just means the
         read-ahead has completed, whether successfully or not. */
--- 280,289 ----
      {
        int rc;
  
!       if (fd_info[cp->fd].flags & FILE_LISTEN)
!       rc = _sys_wait_accept (cp->fd);
!       else
!       rc = _sys_read_ahead (cp->fd);
  
        /* The name char_avail is a misnomer - it really just means the
         read-ahead has completed, whether successfully or not. */

-- 
Kim F. Storm <address@hidden> http://www.cua.dk





reply via email to

[Prev in Thread] Current Thread [Next in Thread]