<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2800.1400" name=GENERATOR>
<STYLE>@page Section1 {size: 595.3pt 841.9pt; margin: 72.0pt 90.0pt 72.0pt 90.0pt; }
P.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 6pt 0cm 0pt; FONT-FAMILY: "Times New Roman"
}
LI.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 6pt 0cm 0pt; FONT-FAMILY: "Times New Roman"
}
DIV.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 6pt 0cm 0pt; FONT-FAMILY: "Times New Roman"
}
H1 {
        FONT-SIZE: 24pt; MARGIN-BOTTOM: 12pt; PAGE-BREAK-BEFORE: always; MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; MARGIN-RIGHT: 0cm; FONT-FAMILY: "Times New Roman"
}
H1.CxSpFirst {
        FONT-SIZE: 24pt; MARGIN-BOTTOM: 0pt; PAGE-BREAK-BEFORE: always; MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; MARGIN-RIGHT: 0cm; FONT-FAMILY: "Times New Roman"
}
H1.CxSpMiddle {
        FONT-SIZE: 24pt; MARGIN-BOTTOM: 0pt; PAGE-BREAK-BEFORE: always; MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; MARGIN-RIGHT: 0cm; FONT-FAMILY: "Times New Roman"
}
H1.CxSpLast {
        FONT-SIZE: 24pt; MARGIN-BOTTOM: 12pt; PAGE-BREAK-BEFORE: always; MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; MARGIN-RIGHT: 0cm; FONT-FAMILY: "Times New Roman"
}
H4 {
        FONT-SIZE: 12pt; MARGIN-LEFT: 53.85pt; MARGIN-RIGHT: 0cm; FONT-FAMILY: "Times New Roman"
}
H5 {
        FONT-SIZE: 10pt; MARGIN-LEFT: 71.75pt; MARGIN-RIGHT: 0cm; FONT-FAMILY: "Times New Roman"
}
A:link {
        COLOR: blue; TEXT-DECORATION: underline
}
SPAN.MsoHyperlink {
        COLOR: blue; TEXT-DECORATION: underline
}
A:visited {
        COLOR: purple; TEXT-DECORATION: underline
}
SPAN.MsoHyperlinkFollowed {
        COLOR: purple; TEXT-DECORATION: underline
}
P.StyleHeading4Left127cm {
        FONT-WEIGHT: bold; FONT-SIZE: 12pt; MARGIN-LEFT: 53.85pt; MARGIN-RIGHT: 0cm; FONT-FAMILY: "Times New Roman"
}
LI.StyleHeading4Left127cm {
        FONT-WEIGHT: bold; FONT-SIZE: 12pt; MARGIN-LEFT: 53.85pt; MARGIN-RIGHT: 0cm; FONT-FAMILY: "Times New Roman"
}
DIV.StyleHeading4Left127cm {
        FONT-WEIGHT: bold; FONT-SIZE: 12pt; MARGIN-LEFT: 53.85pt; MARGIN-RIGHT: 0cm; FONT-FAMILY: "Times New Roman"
}
SPAN.EmailStyle18 {
        COLOR: windowtext; FONT-FAMILY: Arial
}
DIV.Section1 {
        page: Section1
}
OL {
        MARGIN-BOTTOM: 0cm
}
UL {
        MARGIN-BOTTOM: 0cm
}
</STYLE>
</HEAD>
<BODY lang=EN-GB vLink=purple link=blue>
<DIV dir=ltr align=left><FONT size=2>
<P>Hi Ian,</P>
<P></P>
<P>You can also use the standard "thread" or "threading" Python modules, so that 
you don't depend on _apache.</P>
<P></P>
<P>The approach you have is secure but it has the downside of denying any 
concurrent access to the database (if I understand your code correctly). I don't 
know SQLite very much, but it seems that it can handle multithreaded access to 
the database (see </FONT><A href="http://www.sqlite.org/lockingv3.html"><U><FONT 
color=#0000ff size=2>http://www.sqlite.org/lockingv3.html</U></FONT></A><FONT 
size=2>), so it would be better to leverage this. The solution is a connection 
pool.</FONT></P>
<P><FONT size=2></FONT></P>
<P><FONT size=2>You can write a connection pool using the threading.RLock and 
threading.Condition to protect the critical sections, namely the acquisition of 
database connections. The end result is that each thread is guaranteed to have a 
connection of its own, which can be reused as soon the thread release it to the 
pool. It usually speeds things up, and I guess it would be especially useful 
with SQLite. I've been using such a connection pool for a few months now and 
have never looked back since. In your case, it seems that you wrap the SQLite 
connection with an UserDatabase object, so maybe&nbsp;<SPAN 
class=221363108-07072004>you should pool UserDatabase instances instead of 
SQLite connections.</SPAN></FONT></P>
<P><FONT size=2></FONT></P>
<P><FONT size=2>Best regards,</FONT></P>
<P><FONT size=2></FONT></P>
<P><FONT size=2>Nicolas Lehuen</FONT></P></DIV><BR>
<BLOCKQUOTE dir=ltr 
style="PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #0000ff 2px solid; MARGIN-RIGHT: 0px">
  <DIV class=OutlookMessageHeader lang=fr dir=ltr align=left>
  <HR tabIndex=-1>
  <FONT face=Tahoma size=2><B>De&nbsp;:</B> mod_python-bounces@modpython.org 
  [mailto:mod_python-bounces@modpython.org] <B>De la part de</B> Iain 
  Mackay<BR><B>Envoy�&nbsp;:</B> mardi 6 juillet 2004 21:18<BR><B>�&nbsp;:</B> 
  mod_python@modpython.org<BR><B>Objet&nbsp;:</B> [mod_python] Apache on Windows 
  and concurrency<BR></FONT><BR></DIV>
  <DIV></DIV>
  <DIV class=Section1>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Thanks Grisha for being so quickly 
  on the case.</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Session.py also includes the 
  solution to my problem, using the Apache global locks.</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">I now have the following code to 
  protect a section of &nbsp;script that is using the database connection (it 
  uses SQLite but would apply mutatis mutandis to another database). I have 
  restored multi-threading and all works smoothly. </SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">If this is the best way to do 
  this, it might be worth a mention in the next release of the documentation. I 
  suppose ideally application code shouldn�t use _apache.</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">from mod_python import 
  apache</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">import _apache</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">import re</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">import sqlite</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">import 
  userdatabase</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">import sys</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT>&nbsp;</P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">users = None</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">apache.log_error ("userHandler 
  initialising", apache.APLOG_INFO)</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT>&nbsp;</P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">def beginDB 
  (req):</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  _apache._global_lock(req.server, None, 0)</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  global users</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  if not users:</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  try:</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  try:</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  defaultUser = req.get_options ()["defaultUser"]</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  except:</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  defaultUser = "guest"</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  users = userdatabase.UserDatabase\</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (sqlite.connect (req.get_options ()["dbFile"],</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  077, autocommit=1), defaultUser)</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  except:</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  (type, value, tb) = sys.exc_info()</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  apache.log_error ("Cannot access user database: %s (%s)" % (type, 
  value),</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  apache.APLOG_ERR)</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  </SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">def endDB (req):</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  _apache._global_unlock(req.server, None, 0)</SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT>&nbsp;</P></DIV></BLOCKQUOTE></BODY></HTML>