Author: wyoung
Date: Thu Mar  5 19:57:10 2009
New Revision: 2479

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=2479&view=rev
Log:
Several minor clarity and correctness tweaks to threads chapter.

Modified:
    trunk/doc/userman/threads.dbx

Modified: trunk/doc/userman/threads.dbx
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/doc/userman/threads.dbx?rev=2479&r1=2478&r2=2479&view=diff
==============================================================================
--- trunk/doc/userman/threads.dbx (original)
+++ trunk/doc/userman/threads.dbx Thu Mar  5 19:57:10 2009
@@ -25,14 +25,13 @@
   consequences. Everything else is up to you, the programmer, to
   evaluate and enable as and when you need it.</para>
 
-  <para>We&rsquo;re going to assume that you either agree with these
-  views but find yourself needing to use threads for some other
-  reason, or are foolishly disregarding these facts and are going to
-  use threads anyway. Our purpose here is limited to setting down
-  the rules for avoiding problems with MySQL++ in a multi-threaded
-  program. We won&rsquo;t go into the broader issues of thread safety
-  outside the scope of MySQL++. You will need a grounding in threads
-  in general to get the full value of this advice.</para>
+  <para>We&rsquo;re going to assume that you are reading this chapter
+  because you find yourself needing to use threads for some other
+  reason than to speed up MySQL access. Our purpose here is limited
+  to setting down the rules for avoiding problems with MySQL++ in a
+  multi-threaded program. We won&rsquo;t go into the broader issues of
+  thread safety outside the scope of MySQL++. You will need a grounding
+  in threads in general to get the full value of this advice.</para>
 
   <sect2 id="thread-build">
     <title>Build Issues</title>
@@ -77,11 +76,12 @@
         thread-safe one. (The &ldquo;<filename>_r</filename>&rdquo;
         means reentrant.)</para>
 
-        <para>If you&rsquo;re using the Windows binary distribution of
-        MySQL, there are two versions of the client library, but both
-        are thread aware. One just has debugging symbols, and the other
-        doesn&rsquo;t. See <filename>README-Visual-C++.txt</filename>
-        or <filename>README-MinGW.txt</filename> for details.</para>
+        <para>If you&rsquo;re using the Windows binary distribution
+        of MySQL, you should have only one version of the C
+        API library, which should be thread-aware. If you have
+        two, you probably just have separate debug and optimized
+        builds. See <filename>README-Visual-C++.txt</filename> or
+        <filename>README-MinGW.txt</filename> for details.</para>
 
         <para>If you build MySQL from source, you might only get
         one version of the MySQL C API library, and it can have
@@ -224,48 +224,42 @@
 
     <para>You can call
     <methodname>Connection::thread_aware()</methodname> to
-    determine whether MySQL++ and the underlying C API library
-    were both built to be thread-aware. Again, I stress that thread
+    determine whether MySQL++ and the underlying C API library were
+    both built to be thread-aware. I want to stress that thread
     <emphasis>awareness</emphasis> is not the same thing as thread
-    <emphasis>safety</emphasis>: it&rsquo;s still up to you to
-    make your code thread-safe. If this method returns true, it
-    just means it&rsquo;s <emphasis>possible</emphasis> to achieve
-    thread-safety.</para>
-
-    <para>If your program&rsquo;s connection-management strategy allows
-    a thread to use a <classname>Connection</classname> object that
-    another thread created before it creates a connection of its own,
-    you must call <methodname>Connection::thread_start()</methodname>
-    from that thread before it does anything with MySQL++. If a
-    thread creates a new connection before it uses a connection
-    created by another thread, though, it doesn&rsquo;t need to call
-    <methodname>Connection::thread_start()</methodname> because the
-    per-thread resources this allocates are implicitly created upon
-    creation of a connection if necessary.</para>
-
-    <para>This is why the simple
-    <classname>Connection</classname>-per-thread strategy
-    works: each thread that uses MySQL++ creates a connection
-    in that thread, implicitly allocating the per-thread
-    resources at the same time. You never need to call
-    <methodname>Connection::thread_start()</methodname> in this
-    instance. It&rsquo;s not harmful to call this function, just
-    unnecessary.</para>
-
-    <para>A good counterexample is using
-    <classname>ConnectionPool</classname>: you probably do need
-    to call <methodname>Connection::thread_start()</methodname>
-    at the start of each worker thread because you can&rsquo;t
-    usually tell whether you&rsquo;re getting a new connection
-    from the pool, or reusing one that another thread returned
-    to the pool after allocating it. It&rsquo;s possible to
-    conceive of situations where you can guarantee that each pool
-    user always allocates a fresh connection the first time it
-    calls <methodname>ConnectionPool::grab()</methodname>,
-    but thread programming is complex enough that
-    it&rsquo;s best to take the safe path and always call
-    <methodname>Connection::thread_start()</methodname> early in each
-    worker thread.</para>
+    <emphasis>safety</emphasis>: it&rsquo;s still up to you to make
+    your code thread-safe. If this method returns true, it just means
+    it&rsquo;s <emphasis>possible</emphasis> to achieve thread-safety,
+    not that you actually have it.</para>
+
+    <para>If your program&rsquo;s connection-management strategy
+    allows a thread to use a <classname>Connection</classname>
+    object that another thread created, you need to know
+    about <methodname>Connection::thread_start()</methodname>.
+    This function sets up per-thread resources needed to make MySQL
+    server calls. You don&rsquo;t need to call it when you use the
+    simple <classname>Connection</classname>-per-thread strategy,
+    because this function is implicitly called the first time you
+    create a <classname>Connection</classname> in a thread. It&rsquo;s
+    not harmful to call this function from a thread that previously
+    created a <classname>Connection</classname>, just unnecessary. The
+    only time it&rsquo;s necessary is when a thread can make calls
+    to the database server on a <classname>Connection</classname>
+    that another thread created and that thread hasn&rsquo;t already
+    created a <classname>Connection</classname> itself.</para>
+
+    <para>If you use <classname>ConnectionPool</classname>, you should
+    call <methodname>thread_start()</methodname> at the start of each
+    worker thread because you probably can&rsquo;t reliably predict
+    whether your <methodname>grab()</methodname> call will create a new
+    <classname>Connection</classname> or will return one previously
+    returned to the pool from another thread.  It&rsquo;s possible
+    to conceive of situations where you can guarantee that each pool
+    user always creates a fresh <classname>Connection</classname> the
+    first time it calls <methodname>grab()</methodname>, but thread
+    programming is complex enough that it&rsquo;s best to take the
+    safe path and always call <methodname>thread_start()</methodname>
+    early in each worker thread.</para>
 
     <para>Finally, there&rsquo;s the complementary method,
     <methodname>Connection::thread_end()</methodname>. Strictly
@@ -287,23 +281,26 @@
     <title>Sharing MySQL++ Data Structures</title>
 
     <para>We&rsquo;re in the process of making it safer to share
-    MySQL++&rsquo;s data structures across threads.</para>
-
-    <para>By way of illustration, let me explain a problem we had up
-    until MySQL++ v3.0. When you issue a database query that returns
-    rows, you also get information about the columns in each row. Since
-    the column information is the same for each row in the result set,
-    older versions of MySQL++ kept this information in the result set
-    object, and each <ulink url="Row" type="classref"/> kept a pointer
-    back to the result set object that created it so it could access
-    this common data at need. This was fine as long as each result set
-    object outlived the <classname>Row</classname> objects it returned.
-    It required uncommon usage patterns to run into trouble in this area
-    in a single-threaded program, but in a multi-threaded program it was
-    easy. For example, there&rsquo;s frequently a desire to let one
-    connection do the queries, and other threads process the results.
-    You can see how avoiding lifetime problems here would require a
-    careful locking strategy.</para>
+    MySQL++&rsquo;s data structures across threads. Although things
+    are getting better, it&rsquo;s highly doubtful that all problems
+    with this are now fixed. By way of illustration, allow me explain
+    one aspect of this problem and how we solved it in MySQL++
+    3.0.0.</para>
+
+    <para>When you issue a database query that returns rows, you
+    also get information about the columns in each row. Since the
+    column information is the same for each row in the result set,
+    older versions of MySQL++ kept this information in the result
+    set object, and each <ulink url="Row" type="classref"/> kept
+    a pointer back to the result set object that created it so it
+    could access this common data at need. This was fine as long as
+    each result set object outlived the <classname>Row</classname>
+    objects it returned.  It required uncommon usage patterns to run
+    into trouble in this area in a single-threaded program, but in
+    a multi-threaded program it was easy. For example, there&rsquo;s
+    frequently a desire to let one connection do the queries, and other
+    threads process the results.  You can see how avoiding lifetime
+    problems here would require a careful locking strategy.</para>
 
     <para>We got around this in MySQL++ v3.0 by giving these shared data
     structures a lifetime independent of the result set object that
@@ -312,12 +309,12 @@
 
     <para>Although this is now a solved problem, I bring it up because
     there are likely other similar lifetime and sequencing problems
-    waiting to be discovered inside MySQL++. If you would like to help
-    us find these, by all means, share data between threads willy-nilly.
-    We welcome your crash reports on the MySQL++ mailing list. But if
-    you&rsquo;d prefer to avoid problems, it&rsquo;s better to keep all
-    data about a query within a single thread. Between this and the
-    previous section&rsquo;s advice, you should be able to use threads
-    with MySQL++ without trouble.</para>
+    waiting to be discovered inside MySQL++. If you would like to
+    help us find these, by all means, share data between threads
+    willy-nilly.  We welcome your crash reports on the MySQL++
+    mailing list. But if you&rsquo;d prefer to avoid problems,
+    it&rsquo;s better to keep all data about a query within a single
+    thread. Between this and the advice in prior sections, you should
+    be able to use threads with MySQL++ without trouble.</para>
   </sect2>
 </sect1>


_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits

Reply via email to