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" |
| 20 | border="0" height="32" |
| 21 | alt="Previous Page" width="32"></A></td> |
| 22 | <td><A href="internals.html"><img src="up.gif" |
| 23 | border="0" height="32" |
| 24 | alt="Up One Level" width="32"></A></td> |
| 25 | <td><A href="socket-methods.html"><img src="next.gif" |
| 26 | border="0" height="32" |
| 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" |
| 30 | border="0" height="32" |
| 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> |
| 50 | <P> |
| 51 | <EM><EM><EM>There are a number of problems with callbacks. First of all, OpenSSL is written |
| 52 | as a C library, it's not meant to have Python callbacks, so a way around that |
| 53 | is needed. Another problem is thread support. A lot of the OpenSSL I/O |
| 54 | functions can block if the socket is in blocking mode, and then you want other |
| 55 | Python threads to be able to do other things. The real trouble is if you've |
| 56 | released the thread lock to do a potentially blocking operation, and the |
| 57 | operation calls a callback. Then we must take the thread lock back<A NAME="tex2html6" |
Jean-Paul Calderone | 72b8f0f | 2008-02-21 23:57:40 -0500 | [diff] [blame^] | 58 | HREF="#foot934"><SUP>5</SUP></A>. |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 59 | </EM></EM></EM> |
| 60 | <P> |
| 61 | <EM><EM><EM>There are two solutions to the first problem, both of which are necessary. The |
| 62 | first solution to use is if the C callback allows ''userdata'' to be passed to |
| 63 | it (an arbitrary pointer normally). This is great! We can set our Python |
| 64 | function object as the real userdata and emulate userdata for the Python |
| 65 | function in another way. The other solution can be used if an object with an |
| 66 | ''app_data'' system always is passed to the callback. For example, the SSL |
| 67 | object in OpenSSL has app_data functions and in e.g. the verification |
| 68 | callbacks, you can retrieve the related SSL object. What we do is to set our |
| 69 | wrapper <tt class="class">Connection</tt> object as app_data for the SSL object, and we can |
| 70 | easily find the Python callback. |
| 71 | </EM></EM></EM> |
| 72 | <P> |
| 73 | <EM><EM><EM>The other problem is also partially solved by app_data. Since we're associating |
| 74 | our wrapper objects with the ''real'' objects, we can easily access data from |
| 75 | the <tt class="class">Connection</tt> object. The solution then is to simply include a |
| 76 | <tt class="ctype">PyThreadState</tt> variable in the <tt class="class">Connection</tt> declaration, and write |
| 77 | macros similar to <tt class="cfunction">Py_BEGIN_ALLOW_THREADS</tt> and |
| 78 | <tt class="cfunction">Py_END_ALLOW_THREADS</tt> that allows specifying of the |
| 79 | <tt class="ctype">PyThreadState</tt> variable to use. Now we can simply ''begin allow |
| 80 | threads'' before a potentially blocking operation, and ''end allow threads'' |
| 81 | before calling a callback. |
| 82 | </EM></EM></EM> |
| 83 | <P> |
| 84 | <BR><HR><H4>Footnotes</H4> |
| 85 | <DL> |
Jean-Paul Calderone | 72b8f0f | 2008-02-21 23:57:40 -0500 | [diff] [blame^] | 86 | <DT><A NAME="foot934">... back</A><A |
Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 87 | href="callbacks.html#tex2html6"><SUP>5</SUP></A></DT> |
| 88 | <DD>I'm |
| 89 | not sure why this is necessary, but otherwise I get a segmentation violation on |
| 90 | <tt class="cfunction">PyEval_CallObject</tt> |
| 91 | |
| 92 | </DD> |
| 93 | </DL> |
| 94 | <DIV CLASS="navigation"> |
| 95 | <p><hr> |
| 96 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 97 | <tr> |
| 98 | <td><A href="exceptions.html"><img src="previous.gif" |
| 99 | border="0" height="32" |
| 100 | alt="Previous Page" width="32"></A></td> |
| 101 | <td><A href="internals.html"><img src="up.gif" |
| 102 | border="0" height="32" |
| 103 | alt="Up One Level" width="32"></A></td> |
| 104 | <td><A href="socket-methods.html"><img src="next.gif" |
| 105 | border="0" height="32" |
| 106 | alt="Next Page" width="32"></A></td> |
| 107 | <td align="center" width="100%">Python OpenSSL Manual</td> |
| 108 | <td><A href="contents.html"><img src="contents.gif" |
| 109 | border="0" height="32" |
| 110 | alt="Contents" width="32"></A></td> |
| 111 | <td><img src="blank.gif" |
| 112 | border="0" height="32" |
| 113 | alt="" width="32"></td> |
| 114 | <td><img src="blank.gif" |
| 115 | border="0" height="32" |
| 116 | alt="" width="32"></td> |
| 117 | </tr></table> |
| 118 | <b class="navlabel">Previous:</b> <a class="sectref" href="exceptions.html">4.1 Exceptions</A> |
| 119 | <b class="navlabel">Up:</b> <a class="sectref" href="internals.html">4 Internals</A> |
| 120 | <b class="navlabel">Next:</b> <a class="sectref" href="socket-methods.html">4.3 Acessing Socket Methods</A> |
| 121 | <hr> |
| 122 | <span class="release-info">Release 0.6.</span> |
| 123 | </DIV> |
| 124 | <!--End of Navigation Panel--> |
| 125 | |
| 126 | </BODY> |
| 127 | </HTML> |