Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
| 2 | <html> |
| 3 | <head> |
| 4 | <title>4.2 Callbacks </title> |
| 5 | <META NAME="description" CONTENT="4.2 Callbacks "> |
| 6 | <META NAME="keywords" CONTENT="pyOpenSSL"> |
| 7 | <META NAME="resource-type" CONTENT="document"> |
| 8 | <META NAME="distribution" CONTENT="global"> |
| 9 | <link rel="STYLESHEET" href="pyOpenSSL.css"> |
| 10 | <LINK REL="next" href="socket-methods.html"> |
| 11 | <LINK REL="previous" href="exceptions.html"> |
| 12 | <LINK REL="up" href="internals.html"> |
| 13 | <LINK REL="next" href="socket-methods.html"> |
| 14 | </head> |
| 15 | <body> |
| 16 | <DIV CLASS="navigation"> |
| 17 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 18 | <tr> |
| 19 | <td><A href="exceptions.html"><img src="previous.gif" |
Jean-Paul Calderone | 215d51b | 2009-11-13 09:19:21 -0500 | [diff] [blame^] | 20 | border="0" height="32" |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 21 | alt="Previous Page" width="32"></A></td> |
| 22 | <td><A href="internals.html"><img src="up.gif" |
Jean-Paul Calderone | 215d51b | 2009-11-13 09:19:21 -0500 | [diff] [blame^] | 23 | border="0" height="32" |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 24 | alt="Up One Level" width="32"></A></td> |
| 25 | <td><A href="socket-methods.html"><img src="next.gif" |
Jean-Paul Calderone | 215d51b | 2009-11-13 09:19:21 -0500 | [diff] [blame^] | 26 | border="0" height="32" |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 27 | alt="Next Page" width="32"></A></td> |
| 28 | <td align="center" width="100%">Python OpenSSL Manual</td> |
| 29 | <td><A href="contents.html"><img src="contents.gif" |
Jean-Paul Calderone | 215d51b | 2009-11-13 09:19:21 -0500 | [diff] [blame^] | 30 | border="0" height="32" |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 31 | alt="Contents" width="32"></A></td> |
| 32 | <td><img src="blank.gif" |
| 33 | border="0" height="32" |
| 34 | alt="" width="32"></td> |
| 35 | <td><img src="blank.gif" |
| 36 | border="0" height="32" |
| 37 | alt="" width="32"></td> |
| 38 | </tr></table> |
| 39 | <b class="navlabel">Previous:</b> <a class="sectref" href="exceptions.html">4.1 Exceptions</A> |
| 40 | <b class="navlabel">Up:</b> <a class="sectref" href="internals.html">4 Internals</A> |
| 41 | <b class="navlabel">Next:</b> <a class="sectref" href="socket-methods.html">4.3 Acessing Socket Methods</A> |
| 42 | <br><hr> |
| 43 | </DIV> |
| 44 | <!--End of Navigation Panel--> |
| 45 | |
| 46 | <H2><A NAME="SECTION000520000000000000000"> </A> |
| 47 | <BR> |
| 48 | 4.2 Callbacks |
| 49 | </H2> |
Jean-Paul Calderone | 2aa2b33 | 2008-03-06 21:43:14 -0500 | [diff] [blame] | 50 | |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 51 | <P> |
Jean-Paul Calderone | 2aa2b33 | 2008-03-06 21:43:14 -0500 | [diff] [blame] | 52 | There are a number of problems with callbacks. First of all, OpenSSL is written |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 53 | as a C library, it's not meant to have Python callbacks, so a way around that |
| 54 | is needed. Another problem is thread support. A lot of the OpenSSL I/O |
| 55 | functions can block if the socket is in blocking mode, and then you want other |
| 56 | Python threads to be able to do other things. The real trouble is if you've |
Jean-Paul Calderone | 657d3ec | 2008-09-21 18:59:46 -0400 | [diff] [blame] | 57 | released the global CPython interpreter lock to do a potentially blocking |
| 58 | operation, and the operation calls a callback. Then we must take the GIL back, |
| 59 | since calling Python APIs without holding it is not allowed. |
Jean-Paul Calderone | 2aa2b33 | 2008-03-06 21:43:14 -0500 | [diff] [blame] | 60 | |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 61 | <P> |
Jean-Paul Calderone | 2aa2b33 | 2008-03-06 21:43:14 -0500 | [diff] [blame] | 62 | There are two solutions to the first problem, both of which are necessary. The |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 63 | first solution to use is if the C callback allows ''userdata'' to be passed to |
| 64 | it (an arbitrary pointer normally). This is great! We can set our Python |
| 65 | function object as the real userdata and emulate userdata for the Python |
| 66 | function in another way. The other solution can be used if an object with an |
| 67 | ''app_data'' system always is passed to the callback. For example, the SSL |
| 68 | object in OpenSSL has app_data functions and in e.g. the verification |
| 69 | callbacks, you can retrieve the related SSL object. What we do is to set our |
| 70 | wrapper <tt class="class">Connection</tt> object as app_data for the SSL object, and we can |
| 71 | easily find the Python callback. |
Jean-Paul Calderone | 2aa2b33 | 2008-03-06 21:43:14 -0500 | [diff] [blame] | 72 | |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 73 | <P> |
Jean-Paul Calderone | 657d3ec | 2008-09-21 18:59:46 -0400 | [diff] [blame] | 74 | The other problem is solved using thread local variables. Whenever the GIL is |
| 75 | released before calling into an OpenSSL API, the PyThreadState pointer returned |
| 76 | by <tt class="cfunction">PyEval_SaveState</tt> is stored in a global thread local variable |
| 77 | (using Python's own TLS API, <tt class="cfunction">PyThread_set_key_value</tt>). When it is |
| 78 | necessary to re-acquire the GIL, either after the OpenSSL API returns or in a C |
| 79 | callback invoked by that OpenSSL API, the value of the thread local variable is |
| 80 | retrieved (<tt class="cfunction">PyThread_get_key_value</tt>) and used to re-acquire the GIL. |
| 81 | This allows Python threads to execute while OpenSSL APIs are running and allows |
| 82 | use of any particular pyOpenSSL object from any Python thread, since there is |
| 83 | no per-thread state associated with any of these objects and since OpenSSL is |
| 84 | threadsafe (as long as properly initialized, as pyOpenSSL initializes it). |
Jean-Paul Calderone | 2aa2b33 | 2008-03-06 21:43:14 -0500 | [diff] [blame] | 85 | |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 86 | <P> |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 87 | |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 88 | <DIV CLASS="navigation"> |
| 89 | <p><hr> |
| 90 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 91 | <tr> |
| 92 | <td><A href="exceptions.html"><img src="previous.gif" |
Jean-Paul Calderone | 215d51b | 2009-11-13 09:19:21 -0500 | [diff] [blame^] | 93 | border="0" height="32" |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 94 | alt="Previous Page" width="32"></A></td> |
| 95 | <td><A href="internals.html"><img src="up.gif" |
Jean-Paul Calderone | 215d51b | 2009-11-13 09:19:21 -0500 | [diff] [blame^] | 96 | border="0" height="32" |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 97 | alt="Up One Level" width="32"></A></td> |
| 98 | <td><A href="socket-methods.html"><img src="next.gif" |
Jean-Paul Calderone | 215d51b | 2009-11-13 09:19:21 -0500 | [diff] [blame^] | 99 | border="0" height="32" |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 100 | alt="Next Page" width="32"></A></td> |
| 101 | <td align="center" width="100%">Python OpenSSL Manual</td> |
| 102 | <td><A href="contents.html"><img src="contents.gif" |
Jean-Paul Calderone | 215d51b | 2009-11-13 09:19:21 -0500 | [diff] [blame^] | 103 | border="0" height="32" |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 104 | alt="Contents" width="32"></A></td> |
| 105 | <td><img src="blank.gif" |
| 106 | border="0" height="32" |
| 107 | alt="" width="32"></td> |
| 108 | <td><img src="blank.gif" |
| 109 | border="0" height="32" |
| 110 | alt="" width="32"></td> |
| 111 | </tr></table> |
| 112 | <b class="navlabel">Previous:</b> <a class="sectref" href="exceptions.html">4.1 Exceptions</A> |
| 113 | <b class="navlabel">Up:</b> <a class="sectref" href="internals.html">4 Internals</A> |
| 114 | <b class="navlabel">Next:</b> <a class="sectref" href="socket-methods.html">4.3 Acessing Socket Methods</A> |
| 115 | <hr> |
Jean-Paul Calderone | 215d51b | 2009-11-13 09:19:21 -0500 | [diff] [blame^] | 116 | <span class="release-info">Release 0.10.</span> |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 117 | </DIV> |
| 118 | <!--End of Navigation Panel--> |
| 119 | |
| 120 | </BODY> |
| 121 | </HTML> |