Make fsock module thread-safe

This commit is contained in:
Sascha Schumann 1999-12-01 17:07:25 +00:00
parent 14382523bf
commit 94c36e8846
3 changed files with 73 additions and 38 deletions

View file

@ -14,6 +14,7 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Paul Panotzki - Bunyip Information Systems | | Authors: Paul Panotzki - Bunyip Information Systems |
| Jim Winstead (jimw@php.net) | | Jim Winstead (jimw@php.net) |
| Sascha Schumann <sascha@schumann.cx> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -68,7 +69,10 @@
#include "url.h" #include "url.h"
#include "fsock.h" #include "fsock.h"
#ifndef ZTS #ifdef ZTS
static int fsock_globals_id;
#else
static php_fsock_globals fsock_globals;
extern int le_fp; extern int le_fp;
#endif #endif
@ -105,8 +109,6 @@ struct php3i_sockbuf {
size_t chunk_size; size_t chunk_size;
}; };
static struct php3i_sockbuf *phpsockbuf;
typedef struct php3i_sockbuf php3i_sockbuf; typedef struct php3i_sockbuf php3i_sockbuf;
php3_module_entry fsock_module_entry = { php3_module_entry fsock_module_entry = {
@ -387,17 +389,15 @@ PHP_FUNCTION(pfsockopen)
if(sock->readbuf) pefree(sock->readbuf, sock->persistent); \ if(sock->readbuf) pefree(sock->readbuf, sock->persistent); \
if(sock->prev) sock->prev->next = sock->next; \ if(sock->prev) sock->prev->next = sock->next; \
if(sock->next) sock->next->prev = sock->prev; \ if(sock->next) sock->next->prev = sock->prev; \
if(sock == phpsockbuf) \ if(sock == FG(phpsockbuf)) \
phpsockbuf = sock->next; \ FG(phpsockbuf) = sock->next; \
pefree(sock, sock->persistent) pefree(sock, sock->persistent)
static size_t def_chunk_size = CHUNK_SIZE; static void php_cleanup_sockbuf(int persistent FLS_DC)
static void php_cleanup_sockbuf(int persistent)
{ {
php3i_sockbuf *now, *next; php3i_sockbuf *now, *next;
for(now = phpsockbuf; now; now = next) { for(now = FG(phpsockbuf); now; now = next) {
next = now->next; next = now->next;
if(now->persistent == persistent) { if(now->persistent == persistent) {
SOCK_DESTROY(now); SOCK_DESTROY(now);
@ -410,14 +410,15 @@ static void php_cleanup_sockbuf(int persistent)
#define WRITEPTR(sock) ((sock)->readbuf + (sock)->writepos) #define WRITEPTR(sock) ((sock)->readbuf + (sock)->writepos)
#define SOCK_FIND(sock,socket) \ #define SOCK_FIND(sock,socket) \
php3i_sockbuf *sock; \ php3i_sockbuf *sock; \
sock = _php3_sock_find(socket); \ FLS_FETCH(); \
if(!sock) sock = _php3_sock_create(socket) sock = _php3_sock_find(socket FLS_CC); \
if(!sock) sock = _php3_sock_create(socket FLS_CC)
static php3i_sockbuf *_php3_sock_find(int socket) static php3i_sockbuf *_php3_sock_find(int socket FLS_DC)
{ {
php3i_sockbuf *buf = NULL, *tmp; php3i_sockbuf *buf = NULL, *tmp;
for(tmp = phpsockbuf; tmp; tmp = tmp->next) for(tmp = FG(phpsockbuf); tmp; tmp = tmp->next)
if(tmp->socket == socket) { if(tmp->socket == socket) {
buf = tmp; buf = tmp;
break; break;
@ -426,19 +427,19 @@ static php3i_sockbuf *_php3_sock_find(int socket)
return buf; return buf;
} }
static php3i_sockbuf *_php3_sock_create(int socket) static php3i_sockbuf *_php3_sock_create(int socket FLS_DC)
{ {
php3i_sockbuf *sock; php3i_sockbuf *sock;
int persistent = _php3_is_persistent_sock(socket); int persistent = _php3_is_persistent_sock(socket);
sock = pecalloc(sizeof(*sock), 1, persistent); sock = pecalloc(sizeof(*sock), 1, persistent);
sock->socket = socket; sock->socket = socket;
if((sock->next = phpsockbuf)) if((sock->next = FG(phpsockbuf)))
phpsockbuf->prev = sock; FG(phpsockbuf)->prev = sock;
sock->persistent = persistent; sock->persistent = persistent;
sock->is_blocked = 1; sock->is_blocked = 1;
sock->chunk_size = def_chunk_size; sock->chunk_size = FG(def_chunk_size);
phpsockbuf = sock; FG(phpsockbuf) = sock;
return sock; return sock;
} }
@ -446,11 +447,12 @@ static php3i_sockbuf *_php3_sock_create(int socket)
size_t _php3_sock_set_def_chunk_size(size_t size) size_t _php3_sock_set_def_chunk_size(size_t size)
{ {
size_t old; size_t old;
FLS_FETCH();
old = def_chunk_size; old = FG(def_chunk_size);
if(size <= CHUNK_SIZE || size > 0) if(size <= CHUNK_SIZE || size > 0)
def_chunk_size = size; FG(def_chunk_size) = size;
return old; return old;
} }
@ -459,8 +461,9 @@ int _php3_sock_destroy(int socket)
{ {
int ret = 0; int ret = 0;
php3i_sockbuf *sock; php3i_sockbuf *sock;
FLS_FETCH();
sock = _php3_sock_find(socket); sock = _php3_sock_find(socket FLS_CC);
if(sock) { if(sock) {
ret = 1; ret = 1;
SOCK_DESTROY(sock); SOCK_DESTROY(sock);
@ -485,8 +488,9 @@ int _php3_sock_close(int socket)
{ {
int ret = 0; int ret = 0;
php3i_sockbuf *sock; php3i_sockbuf *sock;
FLS_FETCH();
sock = _php3_sock_find(socket); sock = _php3_sock_find(socket FLS_CC);
if(sock) { if(sock) {
if(!sock->persistent) { if(!sock->persistent) {
SOCK_CLOSE(sock->socket); SOCK_CLOSE(sock->socket);
@ -709,11 +713,27 @@ int php_msock_destroy(int *data)
/* }}} */ /* }}} */
/* {{{ php3_minit_fsock */ /* {{{ php3_minit_fsock */
static void fsock_globals_ctor(FLS_D)
{
zend_hash_init(&FG(ht_fsock_keys), 0, NULL, NULL, 1);
zend_hash_init(&FG(ht_fsock_socks), 0, NULL, (int (*)(void *))php_msock_destroy, 1);
FG(def_chunk_size) = CHUNK_SIZE;
FG(phpsockbuf) = NULL;
}
static void fsock_globals_dtor(FLS_D)
{
zend_hash_destroy(&FG(ht_fsock_socks));
zend_hash_destroy(&FG(ht_fsock_keys));
php_cleanup_sockbuf(1 FLS_CC);
}
PHP_MINIT_FUNCTION(fsock) PHP_MINIT_FUNCTION(fsock)
{ {
#ifndef ZTS #ifdef ZTS
zend_hash_init(&PG(ht_fsock_keys), 0, NULL, NULL, 1); fsock_globals_id = ts_allocate_id(sizeof(php_fsock_globals), fsock_globals_ctor, fsock_globals_dtor);
zend_hash_init(&PG(ht_fsock_socks), 0, NULL, (int (*)(void *))php_msock_destroy, 1); #else
fsock_globals_ctor(FLS_C);
#endif #endif
return SUCCESS; return SUCCESS;
} }
@ -723,10 +743,8 @@ PHP_MINIT_FUNCTION(fsock)
PHP_MSHUTDOWN_FUNCTION(fsock) PHP_MSHUTDOWN_FUNCTION(fsock)
{ {
#ifndef ZTS #ifndef ZTS
zend_hash_destroy(&PG(ht_fsock_socks)); fsock_globals_dtor(FLS_C);
zend_hash_destroy(&PG(ht_fsock_keys));
#endif #endif
php_cleanup_sockbuf(1);
return SUCCESS; return SUCCESS;
} }
/* }}} */ /* }}} */
@ -734,7 +752,9 @@ PHP_MSHUTDOWN_FUNCTION(fsock)
PHP_RSHUTDOWN_FUNCTION(fsock) PHP_RSHUTDOWN_FUNCTION(fsock)
{ {
php_cleanup_sockbuf(0); FLS_FETCH();
php_cleanup_sockbuf(0 FLS_CC);
return SUCCESS; return SUCCESS;
} }

View file

@ -77,4 +77,27 @@ PHP_MINIT_FUNCTION(fsock);
PHP_MSHUTDOWN_FUNCTION(fsock); PHP_MSHUTDOWN_FUNCTION(fsock);
PHP_RSHUTDOWN_FUNCTION(fsock); PHP_RSHUTDOWN_FUNCTION(fsock);
typedef struct {
HashTable ht_fsock_keys;
HashTable ht_fsock_socks;
struct php3i_sockbuf *phpsockbuf;
size_t def_chunk_size;
} php_fsock_globals;
#ifdef ZTS
#define FLS_D php_fsock_globals *fsock_globals
#define FLS_DC , FLS_D
#define FLS_C fsock_globals
#define FLS_CC , FLS_C
#define FG(v) (fsock_globals->v)
#define FLS_FETCH() php_fsock_globals *fsock_globals = ts_resource(fsock_globals_id)
#else
#define FLS_D
#define FLS_DC
#define FLS_C
#define FLS_CC
#define FG(v) (fsock_globals.v)
#define FLS_FETCH()
#endif
#endif /* _FSOCK_H */ #endif /* _FSOCK_H */

View file

@ -850,16 +850,8 @@ static void php_new_thread_end_handler(THREAD_T thread_id)
static void core_globals_ctor(php_core_globals *core_globals) static void core_globals_ctor(php_core_globals *core_globals)
{ {
memset(core_globals,0,sizeof(*core_globals)); memset(core_globals,0,sizeof(*core_globals));
zend_hash_init(&core_globals->ht_fsock_keys, 0, NULL, NULL, 1);
zend_hash_init(&core_globals->ht_fsock_socks, 0, NULL, (int (*)(void *))php_msock_destroy, 1);
} }
static void core_globals_dtor(php_core_globals *core_globals)
{
zend_hash_destroy(&core_globals->ht_fsock_keys);
zend_hash_destroy(&core_globals->ht_fsock_socks);
}
#endif #endif
@ -904,7 +896,7 @@ int php_module_startup(sapi_module_struct *sf)
#ifdef ZTS #ifdef ZTS
tsrm_set_new_thread_end_handler(php_new_thread_end_handler); tsrm_set_new_thread_end_handler(php_new_thread_end_handler);
executor_globals = ts_resource(executor_globals_id); executor_globals = ts_resource(executor_globals_id);
core_globals_id = ts_allocate_id(sizeof(php_core_globals), core_globals_ctor, core_globals_dtor); core_globals_id = ts_allocate_id(sizeof(php_core_globals), core_globals_ctor, NULL);
core_globals = ts_resource(core_globals_id); core_globals = ts_resource(core_globals_id);
#endif #endif
EG(error_reporting) = E_ALL & ~E_NOTICE; EG(error_reporting) = E_ALL & ~E_NOTICE;