home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / hplip / base / async_qt.py < prev    next >
Encoding:
Python Source  |  2006-08-30  |  9.5 KB  |  305 lines

  1. # -*- coding: utf-8 -*-
  2. #   Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp
  3. # Modified for hplips 2003/06/20
  4. #   Author: Sam Rushing <rushing@nightmare.com>
  5. # ======================================================================
  6. # Copyright 1996 by Sam Rushing
  7. #
  8. #                         All Rights Reserved
  9. #
  10. # Permission to use, copy, modify, and distribute this software and
  11. # its documentation for any purpose and without fee is hereby
  12. # granted, provided that the above copyright notice appear in all
  13. # copies and that both that copyright notice and this permission
  14. # notice appear in supporting documentation, and that the name of Sam
  15. # Rushing not be used in advertising or publicity pertaining to
  16. # distribution of the software without specific, written prior
  17. # permission.
  18. #
  19. # SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  20. # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
  21. # NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  22. # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  23. # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  24. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  25. # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  26. # ======================================================================
  27. #
  28. # (c) Copyright 2003-2006 Hewlett-Packard Development Company, L.P.
  29. #
  30. # This program is free software; you can redistribute it and/or modify
  31. # it under the terms of the GNU General Public License as published by
  32. # the Free Software Foundation; either version 2 of the License, or
  33. # (at your option) any later version.
  34. #
  35. # This program is distributed in the hope that it will be useful,
  36. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  37. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  38. # GNU General Public License for more details.
  39. #
  40. # You should have received a copy of the GNU General Public License
  41. # along with this program; if not, write to the Free Software
  42. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  43. #
  44. # Modified by: Don Welch
  45. #
  46.  
  47.  
  48.  
  49.  
  50. """
  51. Basic infrastructure for asynchronous socket service clients and servers.
  52.  
  53. There are only two ways to have a program on a single processor do "more
  54. than one thing at a time".  Multi-threaded programming is the simplest and
  55. most popular way to do it, but there is another very different technique,
  56. that lets you have nearly all the advantages of multi-threading, without
  57. actually using multiple threads. it's really only practical if your program
  58. is largely I/O bound. If your program is CPU bound, then pre-emptive
  59. scheduled threads are probably what you really need. Network servers are
  60. rarely CPU-bound, however.
  61.  
  62. If your operating system supports the select() system call in its I/O
  63. library (and nearly all do), then you can use it to juggle multiple
  64. communication channels at once; doing other work while your I/O is taking
  65. place in the "background."  Although this strategy can seem strange and
  66. complex, especially at first, it is in many ways easier to understand and
  67. control than multi-threaded programming. The module documented here solves
  68. many of the difficult problems for you, making the task of building
  69. sophisticated high-performance network servers and clients a snap.
  70.  
  71. NOTICE: This copy of asyncore has been modified from the Python Std Lib version.
  72.  
  73. """
  74.  
  75.  
  76. import select
  77. import socket
  78. import sys
  79. import time
  80. import os
  81. from qt import *
  82. from g import *
  83.  
  84.  
  85. from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \
  86.      ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EAGAIN
  87.  
  88.  
  89. class ExitNow(Exception):
  90.     pass
  91.  
  92.  
  93. channels = {}    
  94.  
  95. class dispatcher(QObject):
  96.     connected = False
  97.     accepting = False
  98.     closing = False
  99.     addr = None
  100.  
  101.     def __init__ (self, sock=None):
  102.         self.sock_write_notifier = None
  103.         self.sock_read_notifier = None
  104.  
  105.         if sock:
  106.             self.set_socket(sock) 
  107.             self.socket.setblocking(0)
  108.             self.connected = True
  109.             try:
  110.                 self.addr = sock.getpeername()
  111.             except socket.error:
  112.                 # The addr isn't crucial
  113.                 pass
  114.         else:
  115.             self.socket = None
  116.         
  117.  
  118.     def add_channel(self): 
  119.         global channels
  120.         channels[self._fileno] = self
  121.         
  122.         self.sock_read_notifier = QSocketNotifier(self._fileno, QSocketNotifier.Read) 
  123.         QObject.connect(self.sock_read_notifier, SIGNAL("activated(int)"), self.handle_read_event)
  124.         
  125.         self.sock_read_notifier.setEnabled(True)
  126.         
  127.         self.sock_write_notifier = QSocketNotifier(self._fileno, QSocketNotifier.Write) 
  128.         QObject.connect(self.sock_write_notifier, SIGNAL("activated(int)"), self.handle_write_event)
  129.         
  130.         self.sock_write_notifier.setEnabled(False)
  131.  
  132.     def del_channel(self): 
  133.         QObject.disconnect(self.sock_read_notifier, SIGNAL("activated(int)"), self.handle_read_event)
  134.         QObject.disconnect(self.sock_write_notifier, SIGNAL("activated(int)"), self.handle_write_event)
  135.  
  136.         self.sock_write_notifier.setEnabled(False)
  137.         self.sock_read_notifier.setEnabled(False)
  138.  
  139.         global channels
  140.         try:
  141.             del channels[self._fileno]
  142.         except KeyError:
  143.             pass 
  144.         
  145.         self._fileno = 0
  146.         
  147.  
  148.     def create_socket(self, family, type):
  149.         self.family_and_type = family, type
  150.         self.socket = socket.socket (family, type)
  151.         self.socket.setblocking(0)
  152.         self._fileno = self.socket.fileno()
  153.         self.add_channel()
  154.  
  155.     def set_socket(self, sock): 
  156.         self.socket = sock
  157.         self._fileno = sock.fileno()
  158.         self.add_channel()
  159.  
  160.     def set_reuse_addr(self):
  161.         # try to re-use a server port if possible
  162.         try:
  163.             self.socket.setsockopt (
  164.                 socket.SOL_SOCKET, socket.SO_REUSEADDR,
  165.                 self.socket.getsockopt (socket.SOL_SOCKET,
  166.                                         socket.SO_REUSEADDR) | 1
  167.                 )
  168.         except socket.error:
  169.             pass
  170.  
  171.  
  172.     # ==================================================
  173.     # socket object methods.
  174.     # ==================================================
  175.  
  176.     def listen (self, num):
  177.         self.accepting = True
  178.         return self.socket.listen(num)
  179.  
  180.     def bind(self, addr):
  181.         self.addr = addr
  182.         return self.socket.bind(addr)
  183.  
  184.     def connect(self, address):
  185.         self.connected = False
  186.         err = self.socket.connect_ex(address)
  187.         
  188.         if err in (EINPROGRESS, EALREADY, EWOULDBLOCK):
  189.             r, w, e = select.select([], [self.socket.fileno()], [], 5.0)
  190.             err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
  191.  
  192.         if err in (0, EISCONN):
  193.             self.addr = address
  194.             self.connected = True
  195.             self.handle_connect()
  196.         else:
  197.             raise socket.error, err
  198.  
  199.     def accept (self):
  200.         try:
  201.             conn, addr = self.socket.accept()
  202.             return conn, addr
  203.         except socket.error, why:
  204.             if why[0] == EWOULDBLOCK:
  205.                 pass
  206.             else:
  207.                 raise socket.error, why
  208.  
  209.     def send (self, data):
  210.         try:
  211.             result = self.socket.send(data)
  212.         except socket.error, why:
  213.             if why[0] == EWOULDBLOCK:
  214.                 return 0
  215.             elif why[0] == EAGAIN:
  216.                 self.sock_write_notifier.setEnabled(True)
  217.                 return 0
  218.             else:
  219.                 raise socket.error, why
  220.         else: # write succeeded
  221.             self.sock_write_notifier.setEnabled(False)
  222.             return result
  223.  
  224.     def recv(self, buffer_size):
  225.         try:
  226.             data = self.socket.recv (buffer_size)
  227.             if not data:
  228.                 # a closed connection is indicated by signaling
  229.                 # a read condition, and having recv() return 0.
  230.                 self.handle_close()
  231.                 return ''
  232.             else:
  233.                 return data
  234.         except socket.error, why:
  235.             # winsock sometimes throws ENOTCONN
  236.             if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]:
  237.                 self.handle_close()
  238.                 return ''
  239.             else:
  240.                 raise socket.error, why
  241.  
  242.     def close (self):
  243.         self.del_channel()
  244.         self.connected = False
  245.         self.socket.close()
  246.  
  247.     # cheap inheritance, used to pass all other attribute
  248.     # references to the underlying socket object.
  249.     def __getattr__ (self, attr):
  250.         return getattr (self.socket, attr)
  251.  
  252.     def handle_read_event(self):
  253.         if self.accepting:
  254.             # for an accepting socket, getting a read implies
  255.             # that we are connected
  256.             if not self.connected:
  257.                 self.connected = True
  258.             self.handle_accept()
  259.         elif not self.connected:
  260.             self.handle_connect()
  261.             self.connected = True
  262.             self.handle_read()
  263.         else:
  264.             self.handle_read()
  265.  
  266.     def handle_write_event(self):
  267.         # getting a write implies that we are connected
  268.         if not self.connected:
  269.             self.handle_connect()
  270.             self.connected = True
  271.         self.handle_write()
  272.  
  273.     def handle_expt_event(self):
  274.         self.handle_expt()
  275.  
  276.     def handle_error(self):
  277.         self.handle_close()
  278.  
  279.     def handle_expt(self):
  280.         raise Error
  281.  
  282.     def handle_read(self):
  283.         raise Error
  284.  
  285.     def handle_write(self):
  286.         raise Error
  287.         
  288.     def handle_connect(self):
  289.         pass
  290.  
  291.     def handle_accept(self):
  292.         raise Error
  293.  
  294.     def handle_close(self):
  295.         self.close()
  296.  
  297.  
  298.  
  299. def close_all(): 
  300.     global channels
  301.     for x in channels.values():
  302.         x.channels.close()
  303.     channels.clear()
  304.  
  305.