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: DBD::Sybase and threading.
Date: Dec 30 2003 1:18AM

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