Changeset 388 for python/vendor/current/Lib/SocketServer.py
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Lib/SocketServer.py
r2 r388 83 83 class will essentially render the service "deaf" while one request is 84 84 being handled -- which may be for a very long time if a client is slow 85 to re qd all the data it has requested. Here a threading or forking85 to read all the data it has requested. Here a threading or forking 86 86 server is appropriate. 87 87 … … 134 134 import sys 135 135 import os 136 import errno 136 137 try: 137 138 import threading … … 148 149 "ThreadingUnixDatagramServer"]) 149 150 151 def _eintr_retry(func, *args): 152 """restart a system call interrupted by EINTR""" 153 while True: 154 try: 155 return func(*args) 156 except (OSError, select.error) as e: 157 if e.args[0] != errno.EINTR: 158 raise 159 150 160 class BaseServer: 151 161 … … 169 179 - server_close() 170 180 - process_request(request, client_address) 181 - shutdown_request(request) 171 182 - close_request(request) 172 183 - handle_error() … … 198 209 self.RequestHandlerClass = RequestHandlerClass 199 210 self.__is_shut_down = threading.Event() 200 self.__s erving= False211 self.__shutdown_request = False 201 212 202 213 def server_activate(self): … … 215 226 another thread. 216 227 """ 217 self.__serving = True218 228 self.__is_shut_down.clear() 219 while self.__serving: 220 # XXX: Consider using another file descriptor or 221 # connecting to the socket to wake this up instead of 222 # polling. Polling reduces our responsiveness to a 223 # shutdown request and wastes cpu at all other times. 224 r, w, e = select.select([self], [], [], poll_interval) 225 if r: 226 self._handle_request_noblock() 227 self.__is_shut_down.set() 229 try: 230 while not self.__shutdown_request: 231 # XXX: Consider using another file descriptor or 232 # connecting to the socket to wake this up instead of 233 # polling. Polling reduces our responsiveness to a 234 # shutdown request and wastes cpu at all other times. 235 r, w, e = _eintr_retry(select.select, [self], [], [], 236 poll_interval) 237 if self in r: 238 self._handle_request_noblock() 239 finally: 240 self.__shutdown_request = False 241 self.__is_shut_down.set() 228 242 229 243 def shutdown(self): … … 234 248 deadlock. 235 249 """ 236 self.__s erving = False250 self.__shutdown_request = True 237 251 self.__is_shut_down.wait() 238 252 … … 260 274 elif self.timeout is not None: 261 275 timeout = min(timeout, self.timeout) 262 fd_sets = select.select([self], [], [], timeout)276 fd_sets = _eintr_retry(select.select, [self], [], [], timeout) 263 277 if not fd_sets[0]: 264 278 self.handle_timeout() … … 282 296 except: 283 297 self.handle_error(request, client_address) 284 self. close_request(request)298 self.shutdown_request(request) 285 299 286 300 def handle_timeout(self): … … 306 320 """ 307 321 self.finish_request(request, client_address) 308 self. close_request(request)322 self.shutdown_request(request) 309 323 310 324 def server_close(self): … … 319 333 """Finish one request by instantiating RequestHandlerClass.""" 320 334 self.RequestHandlerClass(request, client_address, self) 335 336 def shutdown_request(self, request): 337 """Called to shutdown and close an individual request.""" 338 self.close_request(request) 321 339 322 340 def close_request(self, request): … … 360 378 - verify_request(request, client_address) 361 379 - process_request(request, client_address) 380 - shutdown_request(request) 362 381 - close_request(request) 363 382 - handle_error() … … 444 463 return self.socket.accept() 445 464 465 def shutdown_request(self, request): 466 """Called to shutdown and close an individual request.""" 467 try: 468 #explicitly shutdown. socket.close() merely releases 469 #the socket and waits for GC to perform the actual close. 470 request.shutdown(socket.SHUT_WR) 471 except socket.error: 472 pass #some platforms may raise ENOTCONN here 473 self.close_request(request) 474 446 475 def close_request(self, request): 447 476 """Called to clean up an individual request.""" … … 466 495 # No need to call listen() for UDP. 467 496 pass 497 498 def shutdown_request(self, request): 499 # No need to shutdown anything. 500 self.close_request(request) 468 501 469 502 def close_request(self, request): … … 527 560 self.active_children = [] 528 561 self.active_children.append(pid) 529 self.close_request(request) 562 self.close_request(request) #close handle in parent process 530 563 return 531 564 else: … … 534 567 try: 535 568 self.finish_request(request, client_address) 569 self.shutdown_request(request) 536 570 os._exit(0) 537 571 except: 538 572 try: 539 573 self.handle_error(request, client_address) 574 self.shutdown_request(request) 540 575 finally: 541 576 os._exit(1) … … 557 592 try: 558 593 self.finish_request(request, client_address) 559 self. close_request(request)594 self.shutdown_request(request) 560 595 except: 561 596 self.handle_error(request, client_address) 562 self. close_request(request)597 self.shutdown_request(request) 563 598 564 599 def process_request(self, request, client_address): … … 566 601 t = threading.Thread(target = self.process_request_thread, 567 602 args = (request, client_address)) 568 if self.daemon_threads: 569 t.setDaemon (1) 603 t.daemon = self.daemon_threads 570 604 t.start() 571 605 … … 611 645 self.client_address = client_address 612 646 self.server = server 647 self.setup() 613 648 try: 614 self.setup()615 649 self.handle() 650 finally: 616 651 self.finish() 617 finally:618 sys.exc_traceback = None # Help garbage collection619 652 620 653 def setup(self): … … 650 683 wbufsize = 0 651 684 685 # A timeout to apply to the request socket, if not None. 686 timeout = None 687 688 # Disable nagle algorithm for this socket, if True. 689 # Use only when wbufsize != 0, to avoid small packets. 690 disable_nagle_algorithm = False 691 652 692 def setup(self): 653 693 self.connection = self.request 694 if self.timeout is not None: 695 self.connection.settimeout(self.timeout) 696 if self.disable_nagle_algorithm: 697 self.connection.setsockopt(socket.IPPROTO_TCP, 698 socket.TCP_NODELAY, True) 654 699 self.rfile = self.connection.makefile('rb', self.rbufsize) 655 700 self.wfile = self.connection.makefile('wb', self.wbufsize) … … 657 702 def finish(self): 658 703 if not self.wfile.closed: 659 self.wfile.flush() 704 try: 705 self.wfile.flush() 706 except socket.error: 707 # An final socket error may have occurred here, such as 708 # the local error ECONNABORTED. 709 pass 660 710 self.wfile.close() 661 711 self.rfile.close()
Note:
See TracChangeset
for help on using the changeset viewer.