a =Æ*fvNã@sfdZddlZddlZddlZddlZddlZddlZddlmZm Z m Z m Z m Z m Z mZmZmZmZmZmZmZee e eeeehƒZzeWney¢iZYn0dd„ZGdd„deƒZeeefZdd „Zd d „Z d d „Z!dd„Z"d&dd„Z#d'dd„Z$e$Z%d(dd„Z&Gdd„dƒZ'Gdd„de'ƒZ(dd„Z)d)dd „Z*ej+d!krbGd"d#„d#ƒZ,Gd$d%„d%e'ƒZ-dS)*a Basic infrastructure for asynchronous socket service clients and servers. There are only two ways to have a program on a single processor do "more than one thing at a time". Multi-threaded programming is the simplest and most popular way to do it, but there is another very different technique, that lets you have nearly all the advantages of multi-threading, without actually using multiple threads. it's really only practical if your program is largely I/O bound. If your program is CPU bound, then pre-emptive scheduled threads are probably what you really need. Network servers are rarely CPU-bound, however. If your operating system supports the select() system call in its I/O library (and nearly all do), then you can use it to juggle multiple communication channels at once; doing other work while your I/O is taking place in the "background." Although this strategy can seem strange and complex, especially at first, it is in many ways easier to understand and control than multi-threaded programming. The module documented here solves many of the difficult problems for you, making the task of building sophisticated high-performance network servers and clients a snap. éN) ÚEALREADYÚ EINPROGRESSÚ EWOULDBLOCKÚ ECONNRESETÚEINVALÚENOTCONNÚ ESHUTDOWNÚEISCONNÚEBADFÚ ECONNABORTEDÚEPIPEÚEAGAINÚ errorcodec CsFz t |¡WStttfy@|tvr4t|YSd|YS0dS)NzUnknown error %s)ÚosÚstrerrorÚ ValueErrorÚ OverflowErrorÚ NameErrorr)Úerr©rúZpollsterrAr!r/r?rrrÚpoll2¤s(     rEç>@FcCsb|dur t}|r ttdƒr t}nt}|dur>|r^|||ƒq,n |r^|dkr^|||ƒ|d}q>dS)NrBré)r3Úhasattrr'rErB)r=Zuse_pollr>ÚcountZpoll_funrrrÚloopÀs  rJc@s2eZdZdZdZdZdZdZdZe dhƒZ dAdd„Z dd„Z dBdd „Z dCd d „Zejejfd d „ZdDdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„Zd$d%„ZdEd'd(„Zd)d*„Z d+d,„Z!d-d.„Z"d/d0„Z#d1d2„Z$d3d4„Z%d5d6„Z&d7d8„Z'd9d:„Z(d;d<„Z)d=d>„Z*d?d@„Z+dS)FÚ dispatcherFNÚwarningc Csž|durt|_n||_d|_|r”| d¡| ||¡d|_z| ¡|_Wqšty}z.|j t t fvrpd|_n |  |¡‚WYd}~qšd}~00nd|_ dS)NFT)r3Ú_mapÚ_filenoÚ setblockingÚ set_socketÚ connectedZ getpeernameÚaddrr,r-rrÚ del_channelÚsocket)ÚselfÚsockr>rrrrÚ__init__Üs    zdispatcher.__init__cCs–|jjd|jjg}|jr.|jr.| d¡n|jr>| d¡|jdur€z| d|j¡Wn"ty~| t|jƒ¡Yn0dd  |¡t |ƒfS)NÚ.Z listeningrQz%s:%dz <%s at %#x>ú ) Ú __class__rrr9rRr8rQÚ TypeErrorÚreprÚjoinÚid)rUÚstatusrrrÚ__repr__üs     zdispatcher.__repr__cCs|dur|j}|||j<dSr)rMrN)rUr>rrrÚ add_channel szdispatcher.add_channelcCs,|j}|dur|j}||vr"||=d|_dSr)rNrM)rUr>rArrrrSs zdispatcher.del_channelcCs.||f|_t ||¡}| d¡| |¡dS©NF)Zfamily_and_typerTrOrP)rUZfamilyÚtyperVrrrÚ create_sockets   zdispatcher.create_socketcCs||_| ¡|_| |¡dSr)rTÚfilenorNra©rUrVr>rrrrPs zdispatcher.set_socketcCsBz*|j tjtj|j tjtj¡dB¡Wnty<Yn0dS)NrG)rTZ setsockoptÚ SOL_SOCKETZ SO_REUSEADDRÚ getsockoptr,©rUrrrÚset_reuse_addr#s ÿÿþ zdispatcher.set_reuse_addrcCsdS©NTrrirrrr64szdispatcher.readablecCsdSrkrrirrrr77szdispatcher.writablecCs(d|_tjdkr|dkrd}|j |¡S)NTÚnté)r9rÚnamerTÚlisten)rUZnumrrrro>szdispatcher.listencCs||_|j |¡Sr)rRrTÚbind)rUrRrrrrpDszdispatcher.bindcCspd|_d|_|j |¡}|tttfvs8|tkrBtj dkrB||_ dS|dt fvr^||_ |  ¡nt |t|ƒ‚dS)NFTrlr)rQÚ connectingrTZ connect_exrrrrrrnrRr Úhandle_connect_eventr,r)rUÚaddressrrrrÚconnectHs ÿÿ  zdispatcher.connectc Csvz|j ¡\}}WnVty&YdStyh}z,|jtttfvrRWYd}~dS‚WYd}~nd}~00||fSdSr)rTÚacceptr[r,r-rr r )rUZconnrRÚwhyrrrruVs zdispatcher.acceptc Csvz|j |¡}|WStyp}zF|jtkr:WYd}~dS|jtvrZ| ¡WYd}~dS‚WYd}~n d}~00dS©Nr)rTÚsendr,r-rr.r+)rUÚdataÚresultrvrrrrxds   zdispatcher.sendc Cstz(|j |¡}|s | ¡WdS|WSWnFtyn}z.|jtvrX| ¡WYd}~dS‚WYd}~n d}~00dS©Nó)rTÚrecvr+r,r-r.)rUZ buffer_sizeryrvrrrr}qs   zdispatcher.recvc Csld|_d|_d|_| ¡|jdurhz|j ¡Wn4tyf}z|jtt fvrR‚WYd}~n d}~00dSrb) rQr9rqrSrTÚcloser,r-rr )rUrvrrrr~ƒs zdispatcher.closecCstj dt|ƒ¡dS)Nzlog: %s )ÚsysÚstderrr$Ústr)rUÚmessagerrrÚlog“szdispatcher.logÚinfocCs||jvrtd||fƒdS)Nz%s: %s)Úignore_log_typesÚprint)rUr‚rcrrrÚlog_info–s zdispatcher.log_infocCs:|jr| ¡n&|js.|jr$| ¡| ¡n| ¡dSr)r9Ú handle_acceptrQrqrrÚ handle_readrirrrršs  zdispatcher.handle_read_eventcCs@|j tjtj¡}|dkr(t|t|ƒƒ‚| ¡d|_d|_dS)NrTF) rTrhrgÚSO_ERRORr,rÚhandle_connectrQrq©rUrrrrrr¦s zdispatcher.handle_connect_eventcCs*|jr dS|js|jr| ¡| ¡dSr)r9rQrqrrÚ handle_writerirrrr#®s zdispatcher.handle_write_eventcCs0|j tjtj¡}|dkr$| ¡n| ¡dSrw)rTrhrgrŠr+Ú handle_exptrŒrrrr%¹s zdispatcher.handle_expt_eventcCsXtƒ\}}}}z t|ƒ}Wndt|ƒ}Yn0| d||||fd¡| ¡dS)Nz)<__repr__(self) failed for object at %0x>z:uncaptured python exception, closing channel %s (%s:%s %s)Úerror)Úcompact_tracebackr\r^r‡r+)rUZnilÚtÚvÚtbinfoZ self_reprrrrrÈs üù zdispatcher.handle_errorcCs| dd¡dS)Nz!unhandled incoming priority eventrL©r‡rirrrrŽÜszdispatcher.handle_exptcCs| dd¡dS)Nzunhandled read eventrLr”rirrrr‰ßszdispatcher.handle_readcCs| dd¡dS)Nzunhandled write eventrLr”rirrrrâszdispatcher.handle_writecCs| dd¡dS)Nzunhandled connect eventrLr”rirrrr‹åszdispatcher.handle_connectcCs| ¡}|dur|j|ŽdSr)ruÚhandle_accepted)rUZpairrrrrˆèszdispatcher.handle_acceptcCs| ¡| dd¡dS)Nzunhandled accepted eventrL)r~r‡)rUrVrRrrrr•íszdispatcher.handle_acceptedcCs| dd¡| ¡dS)Nzunhandled close eventrL)r‡r~rirrrr+ñs zdispatcher.handle_close)NN)N)N)N)r„),rrrÚdebugrQr9rqÚclosingrRÚ frozensetr…rWr`rarSrTZAF_INETZ SOCK_STREAMrdrPrjr6r7rorprtrurxr}r~rƒr‡rrrr#r%rrŽr‰rr‹rˆr•r+rrrrrKÒsJ         rKc@s6eZdZd dd„Zdd„Zdd„Zdd „Zd d „ZdS) Údispatcher_with_sendNcCst |||¡d|_dSr{)rKrWÚ out_bufferrfrrrrWüszdispatcher_with_send.__init__cCs.d}t ||jdd…¡}|j|d…|_dS)Nri)rKrxrš)rUZnum_sentrrrÚ initiate_sendsz"dispatcher_with_send.initiate_sendcCs | ¡dSr)r›rirrrrsz!dispatcher_with_send.handle_writecCs|j pt|jƒSr)rQÚlenršrirrrr7szdispatcher_with_send.writablecCs0|jr| dt|ƒ¡|j||_| ¡dS)Nz sending %s)r–r‡r\ršr›)rUryrrrrx s zdispatcher_with_send.send)NN)rrrrWr›rr7rxrrrrr™ús  r™cCs‚t ¡\}}}g}|stdƒ‚|rL| |jjj|jjjt|j ƒf¡|j }q~|d\}}}d  dd„|Dƒ¡}|||f|||fS)Nztraceback does not existéÿÿÿÿrYcSsg|] }d|‘qS)z [%s|%s|%s]r)Ú.0ÚxrrrÚ &r|z%compact_traceback..) rÚexc_infoÚAssertionErrorr8Útb_frameÚf_codeÚ co_filenameÚco_namerÚ tb_linenoÚtb_nextr])r‘r’Útbr“ÚfileÚfunctionÚliner„rrrrsýrc Cs|dur t}t| ¡ƒD]j}z | ¡Wqty^}z|jtkrDn|sJ‚WYd}~qd}~0typ‚Yq|s|‚Yq0q| ¡dSr) r3r4Úvaluesr~r,r-r rÚclear)r>Z ignore_allrŸrrrÚ close_all)s     r¯Úposixc@sNeZdZdd„Zdd„Zdd„Zdd„Zdd d „ZeZeZ d d „Z dd„Z d S)Ú file_wrappercCst |¡|_dSr)rÚduprA©rUrArrrrWNszfile_wrapper.__init__cCs*|jdkrtjd|t|d| ¡dS)Nrzunclosed file %r)Úsource)rAÚwarningsÚwarnÚResourceWarningr~rirrrÚ__del__Qs   ÿzfile_wrapper.__del__cGstj|jg|¢RŽSr)rr"rA©rUÚargsrrrr}Wszfile_wrapper.recvcGstj|jg|¢RŽSr)rr$rAr¹rrrrxZszfile_wrapper.sendNcCs(|tjkr|tjkr|sdStdƒ‚dS)Nrz-Only asyncore specific behaviour implemented.)rTrgrŠÚNotImplementedError)rUÚlevelZoptnameÚbuflenrrrrh]s ÿþzfile_wrapper.getsockoptcCs(|jdkrdS|j}d|_t |¡dS)Nrr)rArr~r³rrrr~hs  zfile_wrapper.closecCs|jSr)rArirrrreoszfile_wrapper.fileno)N) rrrrWr¸r}rxrhr"r$r~rerrrrr±Is r±c@seZdZddd„Zdd„ZdS)Úfile_dispatcherNcCsNt |d|¡d|_z | ¡}Wnty2Yn0| |¡t |d¡dS)NTF)rKrWrQreÚAttributeErrorÚset_filerÚ set_blocking)rUrAr>rrrrWts   zfile_dispatcher.__init__cCs"t|ƒ|_|j ¡|_| ¡dSr)r±rTrerNrar³rrrrÀs  zfile_dispatcher.set_file)N)rrrrWrÀrrrrr¾rs r¾)r2N)r2N)rFFNN)NF).Ú__doc__r'rTrr:rµrr-rrrrrrrr r r r r rr˜r.r3rrÚ ExceptionrÚKeyboardInterruptÚ SystemExitrr"r$r&r1rBrEZpoll3rJrKr™rr¯rnr±r¾rrrrÚsD< ÿ    '  *  )