PEPPLER.ORG
Michael Peppler
Sybase Consulting
Menu
Home
Sybase on Linux
Install Guide for Sybase on Linux
General Sybase Resources
General Perl Resources
Freeware
Sybperl
Sybase::Simple
DBD::Sybase
BCP Tool
Bug Tracker
Mailing List Archive
Downloads Directory
FAQs
Sybase on Linux FAQ
Sybperl FAQ
Personal
Michael Peppler's resume

sybperl-l Archive

Up    Prev    Next    

From: Michael Peppler <mpeppler at peppler dot org>
Subject: Re: DBD::Sybase and threading.
Date: Dec 30 2003 6:34PM

FWIW, the same test script using Sybase::CTlib does not fail
immediately. Obviously more testing and validation is needed to make
sure that Sybase::CTlib is really thread-safe, but at least this is at
least an indication that is positive.

Michael

On Mon, 2003-12-29 at 17:18, Michael Peppler wrote:
> A quick test of the threads.pm package with perl 5.8.1 and DBD::Sybase
> shows that DBD::Sybase is NOT thread-safe at this point.
> 
> The problem lies with the calls to cs_ctx_alloc() and ct_config() which
> are both NOT thread-safe. 
> 
> cs_ctx_alloc() is called when the driver is initialized, so one would
> *think* that this would not be a problem, but DBI recreates a new driver
> for each thread that uses DBI calls, and so will call the initialization
> code multiple times.
> 
> The ct_config() issue has to do with setting values in the (shared)
> CS_CONTEXT data structure during the DBI->connect() call. In particular
> the timeout gets set at this point, and that is not thread safe.
> 
> Which all means that there is some work to do before DBD::Sybase can be
> considered for any multi-threaded application.
> 
> FYI - this is the little test script that I used:
> 
> use strict;
> use threads;
> use DBI;
> 
> my $thr1 = threads->new(\&dbi_test);
> my $thr2 = threads->new(\&dbi_test);
> my $thr3 = threads->new(\&dbi_test);
> {
>     local $^W = 0;
>     my $data = $thr1->join;
>     print "Got @$data (thr1)\n";
>     $data = $thr2->join;
>     print "Got @$data (thr2)\n";
>     $data = $thr3->join;
>     print "Got @$data (thr3)\n";
> }
> 
> sub dbi_test {
>     my $dbh = DBI->connect('dbi:Sybase:server=SYBASE', 'sa', '');
>     my $sth = $dbh->prepare("select * from master..sysprocesses where
> spid = \@\@spid");
>     $sth->execute;
>     my @data;
>     while(my $row = $sth->fetch) {
> 	@data = @$row;
>     }
> 
>     return [@data];
> }
> 
> __END__
> 
> This will work sometimes, and sometimes will fail rather badly, with
> things like:
> 
> Open Client Message:
> Message number: LAYER = (1) ORIGIN = (1) SEVERITY = (1) NUMBER = (60)
> Message String: ct_con_alloc(): user api layer: external error: There is
> a usage error.  This routine has been called at an illegal time.
> ct_con_alloc failed at
> /home/mpeppler/src/DBD-Sybase/blib/lib/DBD/Sybase.pm line 90.
> 
> or
> 
> Open Client Message:
> Message number: LAYER = (1) ORIGIN = (1) SEVERITY = (1) NUMBER = (60)
> Message String: ct_callback(CTX): user api layer: external error: There
> is a usage error.  This routine has been called at an illegal time.
> thread failed to start: install_driver(Sybase) failed: DBD::Sybase
> initialize: ct_callback(clientmsg) failed at
> /local/perl-5.8.1/lib/5.8.1/i686-linux-thread-multi/DynaLoader.pm line
> 249.
> 
> Michael
-- 
Michael Peppler                              Data Migrations, Inc.
mpeppler@peppler.org                 http://www.mbay.net/~mpeppler
Sybase T-SQL/OpenClient/OpenServer/C/Perl developer available for short or 
long term contract positions - http://www.mbay.net/~mpeppler/resume.html