Well finally I am 99.9% sure that the problem is with Metabase. I've managed
to bring the code down to the absolute minimum to simplify things and I can
now state the bug clearly:

On Pentium III 500Mhz running WinMe, Apache 1.3.19 and PHP 4.0.5, use of
Metabase calls in custom session handler to update a MySQL database randomly
crash Apache with (again, randomly) errors in either PHP4TS.DLL or
MSVCRT.DLL.

When Apache does not crash, the code does work (I tested this with a simple
variable increment).

When the Metabase session handler is replaced with one using MySQL calls,
the problem goes away.

Entries noticed in Apache's error.log that may be related are:
FATAL:  emalloc():  Unable to allocate 1701082243 bytes
FATAL:  erealloc():  Unable to allocate 369098752 bytes

I've already written to Manuel about this and I'm sure he'll have the
problem figured out in no time but in the meanwhile, I'm posting my code
here so that this post may benefit others trying to do this in the future
(and with the hope that maybe someone can discover something that *I'm*
doing wrong that could be causing all this!)

<?php
/*
 metabase sesssions library

 error: makes Apache crash randomly with errors in PHP4TS.DLL and MSVCRT.DLL
 running on WinMe with Apache 1.3.19 and PHP 4.0.5

 based on the code of Sterling Hughes (PHP Developer's Cookbook,
 pgs. 222 - 224) and Ying Zhang (PHPBuilder, "Custom Session
 Handlers in PHP4,
http://www.phpbuilder.com/columns/ying20000602.php3?page=1)

 metabase by Manuel Lemos ([EMAIL PROTECTED],
         http://www.phpclasses.upperdesign.com/)

 copyright (c) 2001, aral balkan ([EMAIL PROTECTED])
      http://www.aralbalkan.com
*/

// metabase database abstraction layer
require_once "metabase/metabase_parser.php";
require_once "metabase/metabase_manager.php";
require_once "metabase/metabase_database.php";
require_once "metabase/metabase_interface.php";

$SESS_LIFE = get_cfg_var('session.gc_maxlifetime');

// default life of session to an hour
if ($SESS_LIFE == '') { $SESS_LIFE = 3600; }

function on_session_start ($save_path, $session_name)
{
 global $database;

 /*  db_init.php holds the values for
  $db_type, $db_user, $db_pass, $db_host
 */
 require_once('db_init.php');

 $metabase_init = array(
 "Type"=>$db_type,
 "User"=>$db_user,
 "Password"=>$db_pass,
 "Host"=>$db_host,
 "IncludePath"=>"metabase/",
 "Persistent"=>TRUE
 );

 $metabase_error = MetabaseSetupDatabase(&$metabase_init, &$database);

 if ($metabase_error != '') {
  die('Database setup error: '.$metabase_error);
  return false; // failure
 }

 // select database
 $previous_database_name = MetabaseSetDatabase($database, $db_name);
 return true;
}

function on_session_end()
{
 // Nothing needs to be done in this function
 // since we used a persistent connection
 return true;
}

function on_session_read ($key)
{
 global $database;

 $key = MetabaseGetTextFieldValue($database, $key);

 $stmt = "SELECT sessionData FROM sessions";
 $stmt .= " WHERE sessionID = $key";
 $stmt .= " AND sessionExpire > ". time();

 if (!($result = MetabaseQuery($database, $stmt))) {
   // query failed
   echo '> Main query (sql) failed.'.$e;
   echo '> Error: '.MetabaseError($database).$e;
   die();
 }

 $stmt_rows = MetabaseNumberOfRows($database, $result);

 if ($stmt_rows) {
  $sessionData = MetabaseFetchResult($database, $result, 0, 'sessionData');;
  return($sessionData);
 } else {
  return false;
 }
}

function on_session_write ($key, $val)
{
 global $session_db, $SESS_LIFE;
 global $database;

 // convert the text value to a format suitable for use in current database
 $expiry = time() + $SESS_LIFE;
 $key = MetabaseGetTextFieldValue($database, $key);
 $val = MetabaseGetTextFieldValue($database, $val);

 $replace_stmt = "REPLACE INTO sessions (sessionID, sessionData,
sessionExpire)"
     ." values($key, $val, $expiry)";

 $success = MetabaseQuery($database, $replace_stmt);

 return $success;
}

function on_session_destroy ($key)
{
 global $database;

 $key = MetabaseGetTextFieldValue($database, $key);
 $stmt = "DELETE FROM sessions WHERE sessionID = $key";
 $success = MetabaseQuery($database, $stmt);
 return $success;
}

function on_session_gc ($max_lifetime)
{
 global $database;

 $stmt = "delete from sessions where sessionExpire < " . time();
 $success = MetabaseQuery($database, $stmt);
 return $success;
}

// Set the save handlers
session_set_save_handler("on_session_start", "on_session_end",
       "on_session_read", "on_session_write",
       "on_session_destroy", "on_session_gc");

?>

Thanks,
Aral :)

______________________________
([EMAIL PROTECTED])
    New Media Producer, Kismia, Inc.
([EMAIL PROTECTED])
    Adj. Prof., American University
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ



-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to