~exarkun/pyopenssl/trunk

« back to all changes in this revision

Viewing changes to doc/html/callbacks.html

  • Committer: Jean-Paul Calderone
  • Date: 2011-09-11 19:49:43 UTC
  • mfrom: (156.3.22 sphinx-doc)
  • Revision ID: exarkun@divmod.com-20110911194943-ucaan2tzidk7ek5l
Convert the documentation from LaTeX/epytext to Sphinx/ReST

Show diffs side-by-side

added added

removed removed

Lines of Context:
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">&nbsp;</A>
47
 
<BR>
48
 
4.2 Callbacks 
49
 
</H2>
50
 
 
51
 
<P>
52
 
There are a number of problems with callbacks. First of all, OpenSSL is written
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
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.
60
 
 
61
 
<P>
62
 
There are two solutions to the first problem, both of which are necessary. The
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.
72
 
 
73
 
<P>
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).
85
 
 
86
 
<P>
87
 
 
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"
93
 
  border="0" height="32"
94
 
  alt="Previous Page" width="32"></A></td>
95
 
<td><A href="internals.html"><img src="up.gif"
96
 
  border="0" height="32"
97
 
  alt="Up One Level" width="32"></A></td>
98
 
<td><A href="socket-methods.html"><img src="next.gif"
99
 
  border="0" height="32"
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"
103
 
  border="0" height="32"
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>
116
 
<span class="release-info">Release 0.13.</span>
117
 
</DIV>
118
 
<!--End of Navigation Panel-->
119
 
 
120
 
</BODY>
121
 
</HTML>