mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-08 17:50:50 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
912ddaaf61 | ||
|
|
56f7ecae01 | ||
|
|
79b3d341d3 | ||
|
|
b1617d8ac3 |
No files matched your search
@@ -1,4 +0,0 @@
|
||||
## process this file with automake to produce Makefile.am
|
||||
AUTOMAKE_OPTIONS=foreign
|
||||
lib_LIBRARIES=libtsrm.a
|
||||
libtsrm_a_SOURCES = TSRM.c
|
||||
-392
@@ -1,392 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
#include "TSRM.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
typedef struct _tsrm_tls_entry tsrm_tls_entry;
|
||||
|
||||
struct _tsrm_tls_entry {
|
||||
void **storage;
|
||||
int count;
|
||||
THREAD_T thread_id;
|
||||
tsrm_tls_entry *next;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
void (*ctor)(void *resource);
|
||||
void (*dtor)(void *resource);
|
||||
} tsrm_resource_type;
|
||||
|
||||
|
||||
/* The memory manager table */
|
||||
static tsrm_tls_entry **tsrm_tls_table;
|
||||
static int tsrm_tls_table_size;
|
||||
static ts_rsrc_id id_count;
|
||||
|
||||
/* The resource sizes table */
|
||||
static tsrm_resource_type *resource_types_table;
|
||||
static int resource_types_table_size;
|
||||
|
||||
|
||||
static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */
|
||||
|
||||
/* Debug support */
|
||||
static int tsrm_debug(const char *format, ...);
|
||||
static int tsrm_debug_status;
|
||||
|
||||
|
||||
/* Startup TSRM (call once for the entire process) */
|
||||
TSRM_FUNC int tsrm_startup(int expected_threads, int expected_resources, int debug_status)
|
||||
{
|
||||
tsrm_tls_table_size = expected_threads;
|
||||
tsrm_tls_table = (tsrm_tls_entry **) calloc(tsrm_tls_table_size, sizeof(tsrm_tls_entry *));
|
||||
if (!tsrm_tls_table) {
|
||||
return 0;
|
||||
}
|
||||
id_count=0;
|
||||
|
||||
resource_types_table_size = expected_resources;
|
||||
resource_types_table = (tsrm_resource_type *) calloc(resource_types_table_size, sizeof(tsrm_resource_type));
|
||||
if (!resource_types_table) {
|
||||
free(tsrm_tls_table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsmm_mutex = tsrm_mutex_alloc();
|
||||
|
||||
tsrm_debug_status = debug_status;
|
||||
|
||||
tsrm_debug("Started up TSRM, %d expected threads, %d expected resources\n", expected_threads, expected_resources);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Shutdown TSRM (call once for the entire process) */
|
||||
TSRM_FUNC void tsrm_shutdown()
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tsrm_tls_table) {
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
|
||||
|
||||
while (p) {
|
||||
int j;
|
||||
|
||||
next_p = p->next;
|
||||
for (j=0; j<id_count; j++) {
|
||||
free(p->storage[j]);
|
||||
}
|
||||
free(p->storage);
|
||||
free(p);
|
||||
p = next_p;
|
||||
}
|
||||
}
|
||||
free(tsrm_tls_table);
|
||||
}
|
||||
if (resource_types_table) {
|
||||
free(resource_types_table);
|
||||
}
|
||||
tsrm_mutex_free(tsmm_mutex);
|
||||
tsrm_debug("Shutdown TSRM\n");
|
||||
}
|
||||
|
||||
|
||||
/* allocates a new thread-safe-resource id */
|
||||
TSRM_FUNC ts_rsrc_id ts_allocate_id(size_t size, void (*ctor)(void *resource), void (*dtor)(void *resource))
|
||||
{
|
||||
ts_rsrc_id new_id;
|
||||
int i;
|
||||
|
||||
tsrm_debug("Obtaining a new resource id, %d bytes\n", size);
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
/* obtain a resource id */
|
||||
new_id = id_count++;
|
||||
tsrm_debug("Obtained resource id %d\n", new_id);
|
||||
|
||||
/* store the new resource type in the resource sizes table */
|
||||
if (resource_types_table_size < id_count) {
|
||||
resource_types_table = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
|
||||
if (!resource_types_table) {
|
||||
return -1;
|
||||
}
|
||||
resource_types_table_size = id_count;
|
||||
}
|
||||
resource_types_table[new_id].size = size;
|
||||
resource_types_table[new_id].ctor = ctor;
|
||||
resource_types_table[new_id].dtor = dtor;
|
||||
|
||||
/* enlarge the arrays for the already active threads */
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i];
|
||||
|
||||
while (p) {
|
||||
if (p->count < id_count) {
|
||||
int j;
|
||||
|
||||
p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);
|
||||
for (j=p->count; j<id_count; j++) {
|
||||
p->storage[j] = (void *) malloc(resource_types_table[j].size);
|
||||
if (resource_types_table[j].ctor) {
|
||||
resource_types_table[j].ctor(p->storage[j]);
|
||||
}
|
||||
}
|
||||
p->count = id_count;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
tsrm_debug("Successfully allocated new resource id %d\n", new_id);
|
||||
return new_id;
|
||||
}
|
||||
|
||||
|
||||
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
|
||||
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
|
||||
(*thread_resources_ptr)->count = id_count;
|
||||
(*thread_resources_ptr)->thread_id = thread_id;
|
||||
(*thread_resources_ptr)->next = NULL;
|
||||
for (i=0; i<id_count; i++) {
|
||||
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
|
||||
if (resource_types_table[i].ctor) {
|
||||
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* fetches the requested resource for the current thread */
|
||||
void *ts_resource(ts_rsrc_id id)
|
||||
{
|
||||
THREAD_T thread_id = tsrm_thread_id();
|
||||
int hash_value;
|
||||
tsrm_tls_entry *thread_resources;
|
||||
void *resource;
|
||||
|
||||
tsrm_debug("Fetching resource id %d for thread %ld\n", id, (long) thread_id);
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
||||
thread_resources = tsrm_tls_table[hash_value];
|
||||
|
||||
if (!thread_resources) {
|
||||
allocate_new_resource(&tsrm_tls_table[hash_value], thread_id);
|
||||
thread_resources = tsrm_tls_table[hash_value];
|
||||
} else {
|
||||
do {
|
||||
if (thread_resources->thread_id == thread_id) {
|
||||
break;
|
||||
}
|
||||
if (thread_resources->next) {
|
||||
thread_resources = thread_resources->next;
|
||||
} else {
|
||||
allocate_new_resource(&thread_resources->next, thread_id);
|
||||
thread_resources = thread_resources->next;
|
||||
break;
|
||||
}
|
||||
} while (thread_resources);
|
||||
}
|
||||
|
||||
resource = thread_resources->storage[id];
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
tsrm_debug("Successfully fetched resource id %d for thread id %ld - %x\n", id, (long) thread_id, (long) resource);
|
||||
return resource;
|
||||
}
|
||||
|
||||
|
||||
/* frees all resources allocated for the current thread */
|
||||
void ts_free_thread()
|
||||
{
|
||||
THREAD_T thread_id = tsrm_thread_id();
|
||||
int hash_value;
|
||||
tsrm_tls_entry *thread_resources;
|
||||
tsrm_tls_entry *last=NULL;
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
||||
thread_resources = tsrm_tls_table[hash_value];
|
||||
|
||||
while (thread_resources) {
|
||||
if (thread_resources->thread_id == thread_id) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
if (resource_types_table[i].dtor) {
|
||||
resource_types_table[i].dtor(thread_resources->storage[i]);
|
||||
}
|
||||
free(thread_resources->storage[i]);
|
||||
}
|
||||
free(thread_resources->storage);
|
||||
if (last) {
|
||||
last->next = thread_resources->next;
|
||||
} else {
|
||||
tsrm_tls_table[hash_value]=NULL;
|
||||
}
|
||||
free(thread_resources);
|
||||
break;
|
||||
}
|
||||
if (thread_resources->next) {
|
||||
last = thread_resources;
|
||||
}
|
||||
thread_resources = thread_resources->next;
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}
|
||||
|
||||
|
||||
/* deallocates all occurrences of a given id */
|
||||
void ts_free_id(ts_rsrc_id id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Utility Functions
|
||||
*/
|
||||
|
||||
/* Obtain the current thread id */
|
||||
TSRM_FUNC THREAD_T tsrm_thread_id(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return GetCurrentThreadId();
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_self();
|
||||
#elif defined(NSAPI)
|
||||
return systhread_current();
|
||||
#elif defined(PI3WEB)
|
||||
return PIThread_getCurrent();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a mutex */
|
||||
TSRM_FUNC MUTEX_T tsrm_mutex_alloc( void )
|
||||
{
|
||||
MUTEX_T mutexp;
|
||||
|
||||
#ifdef WIN32
|
||||
mutexp = CreateMutex(NULL,FALSE,NULL);
|
||||
#elif defined(PTHREADS)
|
||||
mutexp = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(mutexp,NULL);
|
||||
#elif defined(NSAPI)
|
||||
mutexp = crit_init();
|
||||
#elif defined(PI3WEB)
|
||||
mutexp = PIPlatform_allocLocalMutex();
|
||||
#endif
|
||||
#ifdef THR_DEBUG
|
||||
printf("Mutex created thread: %d\n",mythreadid());
|
||||
#endif
|
||||
return( mutexp );
|
||||
}
|
||||
|
||||
|
||||
/* Free a mutex */
|
||||
TSRM_FUNC void tsrm_mutex_free( MUTEX_T mutexp )
|
||||
{
|
||||
if (mutexp) {
|
||||
#ifdef WIN32
|
||||
CloseHandle(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
free(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
crit_terminate(mutexp);
|
||||
#elif defined(PI3WEB)
|
||||
PISync_delete(mutexp)
|
||||
#endif
|
||||
}
|
||||
#ifdef THR_DEBUG
|
||||
printf("Mutex freed thread: %d\n",mythreadid());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Lock a mutex */
|
||||
TSRM_FUNC int tsrm_mutex_lock( MUTEX_T mutexp )
|
||||
{
|
||||
//tsrm_debug("Mutex locked thread: %ld\n",tsrm_thread_id());
|
||||
#ifdef WIN32
|
||||
return WaitForSingleObject(mutexp,1000);
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_mutex_lock(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
return crit_enter(mutexp);
|
||||
#elif defined(PI3WEB)
|
||||
return PISync_lock(mutexp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Unlock a mutex */
|
||||
TSRM_FUNC int tsrm_mutex_unlock( MUTEX_T mutexp )
|
||||
{
|
||||
//tsrm_debug("Mutex unlocked thread: %ld\n",tsrm_thread_id());
|
||||
#ifdef WIN32
|
||||
return ReleaseMutex(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_mutex_unlock(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
return crit_exit(mutexp);
|
||||
#elif defined(PI3WEB)
|
||||
return PISync_unlock(mutexp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Debug support
|
||||
*/
|
||||
|
||||
static int tsrm_debug(const char *format, ...)
|
||||
{
|
||||
if (tsrm_debug_status) {
|
||||
va_list args;
|
||||
int size;
|
||||
|
||||
va_start(args, format);
|
||||
size = vprintf(format, args);
|
||||
va_end(args);
|
||||
return size;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tsrm_debug_set(int status)
|
||||
{
|
||||
tsrm_debug_status = status;
|
||||
}
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="TSRM" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=TSRM - Win32 Debug_TS
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TSRM.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TSRM.mak" CFG="TSRM - Win32 Debug_TS"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "TSRM - Win32 Debug_TS" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "TSRM - Win32 Release_TS" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "TSRM - Win32 Debug_TS"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "TSRM___Win32_Debug_TS"
|
||||
# PROP BASE Intermediate_Dir "TSRM___Win32_Debug_TS"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug_TS"
|
||||
# PROP Intermediate_Dir "Debug_TS"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "C:\Projects\TSRM" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x40d /d "_DEBUG"
|
||||
# ADD RSC /l 0x40d /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "TSRM - Win32 Release_TS"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "TSRM___Win32_Release_TS"
|
||||
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TS"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release_TS"
|
||||
# PROP Intermediate_Dir "Release_TS"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "TSRM_EXPORTS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x40d /d "NDEBUG"
|
||||
# ADD RSC /l 0x40d /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "TSRM - Win32 Debug_TS"
|
||||
# Name "TSRM - Win32 Release_TS"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TSRM.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TSRM.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _TSRM_H
|
||||
#define _TSRM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "tsrm_config.h"
|
||||
#endif
|
||||
|
||||
#if WIN32||WINNT
|
||||
# include <windows.h>
|
||||
#elif defined(PTHREADS)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
typedef int ts_rsrc_id;
|
||||
|
||||
#if WIN32||WINNT
|
||||
# ifdef TSRM_EXPORTS
|
||||
# define TSRM_API __declspec(dllexport)
|
||||
# else
|
||||
# define TSRM_API __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define TSRM_API
|
||||
#endif
|
||||
|
||||
|
||||
/* Define TSRM_FUNC */
|
||||
#ifdef __cplusplus
|
||||
#define TSRM_FUNC extern "C" TSRM_API
|
||||
#else
|
||||
#define TSRM_FUNC TSRM_API
|
||||
#endif
|
||||
|
||||
|
||||
/* Define THREAD_T and MUTEX_T */
|
||||
#if defined(WIN32)
|
||||
# define THREAD_T DWORD
|
||||
# define MUTEX_T void *
|
||||
#elif defined(PTHREADS)
|
||||
# define THREAD_T pthread_t
|
||||
# define MUTEX_T pthread_mutex_t *
|
||||
#elif defined(NSAPI)
|
||||
# define THREAD_T SYS_THREAD
|
||||
# define MUTEX_T CRITICAL
|
||||
#elif defined(PI3WEB)
|
||||
# define THREAD_T PIThread *
|
||||
# define MUTEX_T PISync *
|
||||
#endif
|
||||
|
||||
|
||||
#define THREAD_HASH_OF(thr,ts) thr%ts
|
||||
|
||||
|
||||
/* startup/shutdown */
|
||||
TSRM_FUNC int tsrm_startup(int expected_threads, int expected_resources, int debug_status);
|
||||
TSRM_FUNC void tsrm_shutdown();
|
||||
|
||||
/* allocates a new thread-safe-resource id */
|
||||
TSRM_FUNC ts_rsrc_id ts_allocate_id(size_t size, void (*ctor)(void *resource), void (*dtor)(void *resource));
|
||||
|
||||
/* fetches the requested resource for the current thread */
|
||||
TSRM_FUNC void *ts_resource(ts_rsrc_id id);
|
||||
|
||||
/* frees all resources allocated for the current thread */
|
||||
TSRM_FUNC void ts_free_thread();
|
||||
|
||||
/* deallocates all occurrences of a given id */
|
||||
TSRM_FUNC void ts_free_id(ts_rsrc_id id);
|
||||
|
||||
|
||||
/* Debug support */
|
||||
TSRM_FUNC void tsrm_debug_set(int status);
|
||||
|
||||
/* utility functions */
|
||||
TSRM_FUNC THREAD_T tsrm_thread_id(void);
|
||||
TSRM_FUNC MUTEX_T tsrm_mutex_alloc(void);
|
||||
TSRM_FUNC void tsrm_mutex_free(MUTEX_T mutexp);
|
||||
TSRM_FUNC int tsrm_mutex_lock(MUTEX_T mutexp);
|
||||
TSRM_FUNC int tsrm_mutex_unlock(MUTEX_T mutexp);
|
||||
|
||||
#endif /* _TSRM_H */
|
||||
@@ -1,7 +0,0 @@
|
||||
#undef PTHREADS
|
||||
|
||||
#ifdef DEFINE_TSRM_VERSION
|
||||
# undef PACKAGE
|
||||
# undef VERSION
|
||||
#endif
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
mv aclocal.m4 aclocal.m4.old 2>/dev/null
|
||||
aclocal
|
||||
if cmp aclocal.m4.old aclocal.m4 > /dev/null 2>&1; then
|
||||
echo "buildconf: keeping ${1}aclocal.m4"
|
||||
mv aclocal.m4.old aclocal.m4
|
||||
else
|
||||
echo "buildconf: created or modified ${1}aclocal.m4"
|
||||
fi
|
||||
|
||||
autoheader
|
||||
|
||||
automake --add-missing --include-deps
|
||||
|
||||
mv configure configure.old 2>/dev/null
|
||||
autoconf
|
||||
if cmp configure.old configure > /dev/null 2>&1; then
|
||||
echo "buildconf: keeping ${1}configure"
|
||||
mv configure.old configure
|
||||
else
|
||||
echo "buildconf: created or modified ${1}configure"
|
||||
fi
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl
|
||||
dnl Minimalistic configure.in for TSRM.
|
||||
dnl
|
||||
|
||||
AC_INIT(TSRM.c)
|
||||
AM_INIT_AUTOMAKE(TSRM, 1.0)
|
||||
AM_CONFIG_HEADER(tsrm_config.h)
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_C_O
|
||||
AC_PROG_RANLIB
|
||||
|
||||
AC_CHECK_LIB(pthread, pthread_create, [
|
||||
AC_DEFINE(PTHREADS)
|
||||
LIBS="$LIBS -lpthread"
|
||||
],[
|
||||
AC_MSG_ERROR(You need pthreads to build TSRM.)
|
||||
])
|
||||
|
||||
AC_CHECK_HEADERS(stdarg.h)
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
||||
+1
-1
@@ -367,7 +367,7 @@ expr_without_variable:
|
||||
T_LIST '(' { do_list_init(CLS_C); } assignment_list ')' '=' expr { do_list_end(&$$, &$7 CLS_CC); }
|
||||
| w_cvar '=' expr { do_assign(&$$, &$1, &$3 CLS_CC); }
|
||||
| w_cvar '=' '&' w_cvar { do_assign_ref(&$$, &$1, &$4 CLS_CC); }
|
||||
| w_cvar '=' T_NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$2, &$1, &$3, &$4 CLS_CC); } ctor_arguments { do_end_new_object(&$4, &$3, &$6 CLS_CC); do_extended_fcall_end(CLS_C); $$ = $2;}
|
||||
| T_NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$1, &$2 CLS_CC); } ctor_arguments { do_end_new_object(&$$, &$2, &$1, &$4 CLS_CC); do_extended_fcall_end(CLS_C);}
|
||||
| rw_cvar T_PLUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar T_MINUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar T_MUL_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 CLS_CC); }
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ typedef struct _zend_function_entry {
|
||||
|
||||
typedef struct _zend_property_reference {
|
||||
int type; /* read, write or r/w */
|
||||
zval **object;
|
||||
zval *object;
|
||||
zend_llist elements_list;
|
||||
} zend_property_reference;
|
||||
|
||||
|
||||
+8
-5
@@ -1332,7 +1332,7 @@ void do_pop_object(znode *object CLS_DC)
|
||||
}
|
||||
|
||||
|
||||
void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode *class_name CLS_DC)
|
||||
void do_begin_new_object(znode *new_token, znode *class_name CLS_DC)
|
||||
{
|
||||
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
|
||||
unsigned char *ptr = NULL;
|
||||
@@ -1343,12 +1343,14 @@ void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode
|
||||
opline->op1 = *class_name;
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
do_assign(result, variable, &opline->result CLS_CC);
|
||||
//*result = opline->result;
|
||||
//do_assign(result, variable, &opline->result CLS_CC);
|
||||
|
||||
|
||||
new_token->u.opline_num = get_next_op_number(CG(active_op_array));
|
||||
opline = get_next_op(CG(active_op_array) CLS_CC);
|
||||
opline->opcode = ZEND_JMP_NO_CTOR;
|
||||
opline->op1 = *result;
|
||||
opline->op1 = (opline-1)->result;
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
if (class_name->op_type == IS_CONST) {
|
||||
@@ -1356,14 +1358,14 @@ void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode
|
||||
}
|
||||
opline = get_next_op(CG(active_op_array) CLS_CC);
|
||||
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
|
||||
opline->op1 = *result;
|
||||
opline->op1 = (opline-2)->result;
|
||||
opline->op2 = *class_name;
|
||||
opline->extended_value = ZEND_MEMBER_FUNC_CALL | ZEND_CTOR_CALL;
|
||||
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *));
|
||||
}
|
||||
|
||||
|
||||
void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list CLS_DC)
|
||||
void do_end_new_object(znode *result, znode *class_name, znode *new_token, znode *argument_list CLS_DC)
|
||||
{
|
||||
znode ctor_result;
|
||||
|
||||
@@ -1374,6 +1376,7 @@ void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list
|
||||
do_free(&ctor_result CLS_CC);
|
||||
|
||||
CG(active_op_array)->opcodes[new_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
|
||||
*result = CG(active_op_array)->opcodes[new_token->u.opline_num].op1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -295,8 +295,8 @@ void do_push_object(znode *object CLS_DC);
|
||||
void do_pop_object(znode *object CLS_DC);
|
||||
|
||||
|
||||
void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode *class_name CLS_DC);
|
||||
void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list CLS_DC);
|
||||
void do_begin_new_object(znode *new_token, znode *class_name CLS_DC);
|
||||
void do_end_new_object(znode *result, znode *class_name, znode *new_token, znode *argument_list CLS_DC);
|
||||
|
||||
void do_fetch_constant(znode *result, znode *constant_name, int mode CLS_DC);
|
||||
|
||||
|
||||
+57
-14
@@ -136,6 +136,34 @@ static inline zval *_get_zval_ptr(znode *node, temp_variable *Ts, int *should_fr
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline zval *_get_object_zval_ptr(znode *node, temp_variable *Ts, int *should_free ELS_DC)
|
||||
{
|
||||
switch(node->op_type) {
|
||||
case IS_TMP_VAR:
|
||||
*should_free = 1;
|
||||
return &Ts[node->u.var].tmp_var;
|
||||
break;
|
||||
case IS_VAR:
|
||||
if (Ts[node->u.var].var) {
|
||||
PZVAL_UNLOCK(*Ts[node->u.var].var);
|
||||
*should_free = 0;
|
||||
return *Ts[node->u.var].var;
|
||||
} else {
|
||||
*should_free = 1;
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case IS_UNUSED:
|
||||
return NULL;
|
||||
break;
|
||||
#if DEBUG_ZEND
|
||||
default:
|
||||
zend_error(E_ERROR, "Unknown temporary variable type");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline zval **_get_zval_ptr_ptr(znode *node, temp_variable *Ts ELS_DC)
|
||||
{
|
||||
@@ -720,7 +748,7 @@ static inline void zend_fetch_property_address(znode *result, znode *op1, znode
|
||||
zend_property_reference property_reference;
|
||||
zend_overloaded_element overloaded_element;
|
||||
|
||||
property_reference.object = container_ptr;
|
||||
property_reference.object = container;
|
||||
property_reference.type = type;
|
||||
zend_llist_init(&property_reference.elements_list, sizeof(zend_overloaded_element), NULL, 0);
|
||||
overloaded_element.element = *get_zval_ptr(op2, Ts, &free_op2, type);
|
||||
@@ -791,7 +819,7 @@ static zval get_overloaded_property(ELS_D)
|
||||
zval result;
|
||||
|
||||
zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference);
|
||||
result = (*(property_reference->object))->value.obj.ce->handle_property_get(property_reference);
|
||||
result = (property_reference->object)->value.obj.ce->handle_property_get(property_reference);
|
||||
|
||||
zend_llist_destroy(&property_reference->elements_list);
|
||||
|
||||
@@ -805,7 +833,7 @@ static void set_overloaded_property(zval *value ELS_DC)
|
||||
zend_property_reference *property_reference;
|
||||
|
||||
zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference);
|
||||
(*(property_reference->object))->value.obj.ce->handle_property_set(property_reference, value);
|
||||
(property_reference->object)->value.obj.ce->handle_property_set(property_reference, value);
|
||||
|
||||
zend_llist_destroy(&property_reference->elements_list);
|
||||
|
||||
@@ -818,7 +846,7 @@ static void call_overloaded_function(int arg_count, zval *return_value, HashTabl
|
||||
zend_property_reference *property_reference;
|
||||
|
||||
zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference);
|
||||
(*(property_reference->object))->value.obj.ce->handle_function_call(arg_count, return_value, list, plist, *property_reference->object, property_reference);
|
||||
(property_reference->object)->value.obj.ce->handle_function_call(arg_count, return_value, list, plist, property_reference->object, property_reference);
|
||||
zend_llist_destroy(&property_reference->elements_list);
|
||||
|
||||
zend_stack_del_top(&EG(overloaded_objects_stack));
|
||||
@@ -844,7 +872,7 @@ void execute(zend_op_array *op_array ELS_DC)
|
||||
zend_function_state function_state;
|
||||
HashTable *calling_symbol_table;
|
||||
zend_function *function_being_called=NULL;
|
||||
zval **object_ptr=NULL;
|
||||
zval *object_ptr=NULL;
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
temp_variable *Ts = (temp_variable *) do_alloca(sizeof(temp_variable)*op_array->T);
|
||||
#else
|
||||
@@ -1270,7 +1298,9 @@ binary_assign_op_addr: {
|
||||
|
||||
if (opline->extended_value & ZEND_CTOR_CALL) {
|
||||
/* constructor call */
|
||||
PZVAL_LOCK(*Ts[opline->op1.u.var].var);
|
||||
if (opline->op1.op_type == IS_VAR) {
|
||||
PZVAL_LOCK(*Ts[opline->op1.u.var].var);
|
||||
}
|
||||
if (opline->op2.op_type==IS_VAR) {
|
||||
PZVAL_LOCK(*Ts[opline->op2.u.var].var);
|
||||
}
|
||||
@@ -1295,11 +1325,11 @@ binary_assign_op_addr: {
|
||||
object_ptr=NULL;
|
||||
}
|
||||
} else { /* used for member function calls */
|
||||
object_ptr = get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_R);
|
||||
|
||||
object_ptr = _get_object_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R);
|
||||
|
||||
|
||||
if (!object_ptr
|
||||
|| ((*object_ptr)->type==IS_OBJECT && (*object_ptr)->value.obj.ce->handle_function_call)) { /* overloaded function call */
|
||||
|| (object_ptr->type==IS_OBJECT && object_ptr->value.obj.ce->handle_function_call)) { /* overloaded function call */
|
||||
zend_overloaded_element overloaded_element;
|
||||
zend_property_reference *property_reference;
|
||||
|
||||
@@ -1322,10 +1352,10 @@ binary_assign_op_addr: {
|
||||
goto overloaded_function_call_cont;
|
||||
}
|
||||
|
||||
if ((*object_ptr)->type != IS_OBJECT) {
|
||||
if (object_ptr->type != IS_OBJECT) {
|
||||
zend_error(E_ERROR, "Call to a member function on a non-object");
|
||||
}
|
||||
active_function_table = &(*object_ptr)->value.obj.ce->function_table;
|
||||
active_function_table = &object_ptr->value.obj.ce->function_table;
|
||||
}
|
||||
} else { /* function pointer */
|
||||
object_ptr = NULL;
|
||||
@@ -1359,7 +1389,7 @@ do_fcall_common:
|
||||
zend_ptr_stack_push(&EG(argument_stack), (void *) opline->extended_value);
|
||||
if (function_state.function->type==ZEND_INTERNAL_FUNCTION) {
|
||||
var_uninit(&Ts[opline->result.u.var].tmp_var);
|
||||
((zend_internal_function *) function_state.function)->handler(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list), (object_ptr?*object_ptr:NULL));
|
||||
((zend_internal_function *) function_state.function)->handler(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list), (object_ptr?object_ptr:NULL));
|
||||
} else if (function_state.function->type==ZEND_USER_FUNCTION) {
|
||||
if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
|
||||
/*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
|
||||
@@ -1374,12 +1404,23 @@ do_fcall_common:
|
||||
if (opline->opcode==ZEND_DO_FCALL_BY_NAME
|
||||
&& object_ptr
|
||||
&& function_being_called->type!=ZEND_OVERLOADED_FUNCTION) {
|
||||
/*
|
||||
zval *dummy = (zval *) emalloc(sizeof(zval)), **this_ptr;
|
||||
|
||||
var_uninit(dummy);
|
||||
INIT_PZVAL(dummy);
|
||||
zend_hash_update_ptr(function_state.function_symbol_table, "this", sizeof("this"), dummy, sizeof(zval *), (void **) &this_ptr);
|
||||
zend_assign_to_variable_reference(NULL, this_ptr, object_ptr, NULL ELS_CC);
|
||||
*/
|
||||
//zval *dummy = (zval *) emalloc(sizeof(zval));
|
||||
zval **this_ptr;
|
||||
|
||||
//var_uninit(dummy);
|
||||
//INIT_PZVAL(dummy);
|
||||
zend_hash_update_ptr(function_state.function_symbol_table, "this", sizeof("this"), NULL, sizeof(zval *), (void **) &this_ptr);
|
||||
*this_ptr = object_ptr;
|
||||
object_ptr->refcount++;
|
||||
//zend_assign_to_variable_reference(NULL, this_ptr, object_ptr, NULL ELS_CC);
|
||||
object_ptr = NULL;
|
||||
}
|
||||
original_return_value = EG(return_value);
|
||||
@@ -1850,8 +1891,10 @@ send_by_ref:
|
||||
break;
|
||||
case ZEND_JMP_NO_CTOR: {
|
||||
zval *object;
|
||||
|
||||
PZVAL_LOCK(*Ts[opline->op1.u.var].var);
|
||||
|
||||
if (opline->op1.op_type == IS_VAR) {
|
||||
PZVAL_LOCK(*Ts[opline->op1.u.var].var);
|
||||
}
|
||||
object = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R);
|
||||
if (!object->value.obj.ce->handle_function_call
|
||||
&& !zend_hash_exists(&object->value.obj.ce->function_table, object->value.obj.ce->name, object->value.obj.ce->name_length+1)) {
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension pcre
|
||||
|
||||
dnl By default we'll compile and link against the bundled PCRE library
|
||||
dnl if DIR is supplied, we'll use that for linking
|
||||
|
||||
AC_MSG_CHECKING(whether to include PCRE support)
|
||||
AC_ARG_WITH(pcre-regex,
|
||||
[ --without-pcre-regex Don't include Perl Compatible Regular Expressions support],[
|
||||
if test "$withval" = "yes"; then
|
||||
EXTRA_LIBS="-L$abs_builddir/ext/pcre/pcrelib -lpcre $EXTRA_LIBS"
|
||||
PCRE_SUBDIR="pcrelib"
|
||||
AC_DEFINE(HAVE_PCRE, 1)
|
||||
AC_MSG_RESULT(yes)
|
||||
PHP_EXTENSION(pcre)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
],[
|
||||
EXTRA_LIBS="-L$abs_builddir/ext/pcre/pcrelib -lpcre $EXTRA_LIBS"
|
||||
PCRE_SUBDIR="pcrelib"
|
||||
AC_DEFINE(HAVE_PCRE, 1)
|
||||
AC_MSG_RESULT(yes)
|
||||
PHP_EXTENSION(pcre)
|
||||
])
|
||||
AC_SUBST(PCRE_SUBDIR)
|
||||
+1
-1
@@ -204,7 +204,7 @@
|
||||
/* Define if you have the setlocale function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
#define HAVE_LOCALE_H
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define if you have the setvbuf function. */
|
||||
#ifndef HAVE_BINDLIB
|
||||
|
||||
Reference in new issue
Block a user