blob: 0275e75488e449eab7d7ca09c1cd07d004949f15 [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001<!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 Calderone215d51b2009-11-13 09:19:21 -050020 border="0" height="32"
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050021 alt="Previous Page" width="32"></A></td>
22<td><A href="internals.html"><img src="up.gif"
Jean-Paul Calderone215d51b2009-11-13 09:19:21 -050023 border="0" height="32"
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050024 alt="Up One Level" width="32"></A></td>
25<td><A href="socket-methods.html"><img src="next.gif"
Jean-Paul Calderone215d51b2009-11-13 09:19:21 -050026 border="0" height="32"
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050027 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 Calderone215d51b2009-11-13 09:19:21 -050030 border="0" height="32"
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050031 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">&nbsp;</A>
47<BR>
484.2 Callbacks
49</H2>
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -050050
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050051<P>
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -050052There are a number of problems with callbacks. First of all, OpenSSL is written
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050053as a C library, it's not meant to have Python callbacks, so a way around that
54is needed. Another problem is thread support. A lot of the OpenSSL I/O
55functions can block if the socket is in blocking mode, and then you want other
56Python threads to be able to do other things. The real trouble is if you've
Jean-Paul Calderone657d3ec2008-09-21 18:59:46 -040057released the global CPython interpreter lock to do a potentially blocking
58operation, and the operation calls a callback. Then we must take the GIL back,
59since calling Python APIs without holding it is not allowed.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -050060
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050061<P>
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -050062There are two solutions to the first problem, both of which are necessary. The
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050063first solution to use is if the C callback allows ''userdata'' to be passed to
64it (an arbitrary pointer normally). This is great! We can set our Python
65function object as the real userdata and emulate userdata for the Python
66function 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
68object in OpenSSL has app_data functions and in e.g. the verification
69callbacks, you can retrieve the related SSL object. What we do is to set our
70wrapper <tt class="class">Connection</tt> object as app_data for the SSL object, and we can
71easily find the Python callback.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -050072
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050073<P>
Jean-Paul Calderone657d3ec2008-09-21 18:59:46 -040074The other problem is solved using thread local variables. Whenever the GIL is
75released before calling into an OpenSSL API, the PyThreadState pointer returned
76by <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
78necessary to re-acquire the GIL, either after the OpenSSL API returns or in a C
79callback invoked by that OpenSSL API, the value of the thread local variable is
80retrieved (<tt class="cfunction">PyThread_get_key_value</tt>) and used to re-acquire the GIL.
81This allows Python threads to execute while OpenSSL APIs are running and allows
82use of any particular pyOpenSSL object from any Python thread, since there is
83no per-thread state associated with any of these objects and since OpenSSL is
84threadsafe (as long as properly initialized, as pyOpenSSL initializes it).
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -050085
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050086<P>
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050087
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050088<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 Calderone215d51b2009-11-13 09:19:21 -050093 border="0" height="32"
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050094 alt="Previous Page" width="32"></A></td>
95<td><A href="internals.html"><img src="up.gif"
Jean-Paul Calderone215d51b2009-11-13 09:19:21 -050096 border="0" height="32"
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050097 alt="Up One Level" width="32"></A></td>
98<td><A href="socket-methods.html"><img src="next.gif"
Jean-Paul Calderone215d51b2009-11-13 09:19:21 -050099 border="0" height="32"
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500100 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 Calderone215d51b2009-11-13 09:19:21 -0500103 border="0" height="32"
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500104 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 Calderone26ebc9e2011-04-11 19:57:10 -0400116<span class="release-info">Release 0.12.</span>
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500117</DIV>
118<!--End of Navigation Panel-->
119
120</BODY>
121</HTML>