dmitry Fri Nov 10 11:42:40 2006 UTC
Modified files:
/php-src/win32 globals.c php_win32_globals.h registry.c
/php-src/main main.c
/php-src/ext/standard basic_functions.c
Log:
Implemented registry cache that prevent registry lookup on each request. In
case of modification of corresponding registry-tree PHP will reload it
automatic.
http://cvs.php.net/viewvc.cgi/php-src/win32/globals.c?r1=1.7&r2=1.8&diff_format=u
Index: php-src/win32/globals.c
diff -u php-src/win32/globals.c:1.7 php-src/win32/globals.c:1.8
--- php-src/win32/globals.c:1.7 Fri Nov 10 09:56:37 2006
+++ php-src/win32/globals.c Fri Nov 10 11:42:40 2006
@@ -16,10 +16,11 @@
+----------------------------------------------------------------------+
*/
-/* $Id: globals.c,v 1.7 2006/11/10 09:56:37 dmitry Exp $ */
+/* $Id: globals.c,v 1.8 2006/11/10 11:42:40 dmitry Exp $ */
#include "php.h"
#include "php_win32_globals.h"
+#include "syslog.h"
#ifdef ZTS
PHPAPI int php_win32_core_globals_id;
@@ -33,6 +34,26 @@
memset(wg, 0, sizeof(*wg));
}
+void php_win32_core_globals_dtor(void *vg TSRMLS_DC)
+{
+ php_win32_core_globals *wg = (php_win32_core_globals*)vg;
+
+ if (wg->registry_key) {
+ RegCloseKey(wg->registry_key);
+ wg->registry_key = NULL;
+ }
+ if (wg->registry_event) {
+ CloseHandle(wg->registry_event);
+ wg->registry_event = NULL;
+ }
+ if (wg->registry_directories) {
+ zend_hash_destroy(wg->registry_directories);
+ free(wg->registry_directories);
+ wg->registry_directories = NULL;
+ }
+}
+
+
PHP_RSHUTDOWN_FUNCTION(win32_core_globals)
{
php_win32_core_globals *wg =
@@ -43,7 +64,10 @@
#endif
;
- memset(wg, 0, sizeof(*wg));
+ closelog();
+ wg->starttime.tv_sec = 0;
+ wg->lasttime = 0;
+
return SUCCESS;
}
http://cvs.php.net/viewvc.cgi/php-src/win32/php_win32_globals.h?r1=1.6&r2=1.7&diff_format=u
Index: php-src/win32/php_win32_globals.h
diff -u php-src/win32/php_win32_globals.h:1.6
php-src/win32/php_win32_globals.h:1.7
--- php-src/win32/php_win32_globals.h:1.6 Fri Nov 10 09:56:37 2006
+++ php-src/win32/php_win32_globals.h Fri Nov 10 11:42:40 2006
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_win32_globals.h,v 1.6 2006/11/10 09:56:37 dmitry Exp $ */
+/* $Id: php_win32_globals.h,v 1.7 2006/11/10 11:42:40 dmitry Exp $ */
#ifndef PHP_WIN32_GLOBALS_H
#define PHP_WIN32_GLOBALS_H
@@ -41,9 +41,14 @@
/* time */
struct timeval starttime;
__int64 lasttime, freq;
+
+ HKEY registry_key;
+ HANDLE registry_event;
+ HashTable *registry_directories;
};
void php_win32_core_globals_ctor(void *vg TSRMLS_DC);
+void php_win32_core_globals_dtor(void *vg TSRMLS_DC);
PHP_RSHUTDOWN_FUNCTION(win32_core_globals);
#endif
http://cvs.php.net/viewvc.cgi/php-src/win32/registry.c?r1=1.17&r2=1.18&diff_format=u
Index: php-src/win32/registry.c
diff -u php-src/win32/registry.c:1.17 php-src/win32/registry.c:1.18
--- php-src/win32/registry.c:1.17 Thu Aug 3 13:54:20 2006
+++ php-src/win32/registry.c Fri Nov 10 11:42:40 2006
@@ -1,5 +1,6 @@
#include "php.h"
#include "php_ini.h"
+#include "php_win32_globals.h"
#define PHP_REGISTRY_KEY "SOFTWARE\\PHP"
@@ -56,13 +57,135 @@
return 0;
}
+static int LoadDirectory(HashTable *directories, HKEY key, char *path, int
path_len, HashTable *parent_ht)
+{
+ DWORD keys, values, max_key, max_name, max_value;
+ int ret = 0;
+ HashTable *ht = NULL;
+
+ if (RegQueryInfoKey(key, NULL, NULL, NULL, &keys, &max_key, NULL,
&values, &max_name, &max_value, NULL, NULL) == ERROR_SUCCESS) {
+
+ if (values) {
+ DWORD i;
+ char *name = (char*)emalloc(max_name+1);
+ char *value = (char*)emalloc(max_value+1);
+ DWORD name_len, type, value_len;
+ zval *data;
+
+ for (i = 0; i < values; i++) {
+ name_len = max_name+1;
+ value_len = max_value+1;
+ if (RegEnumValue(key, i, name, &name_len, NULL,
&type, value, &value_len) == ERROR_SUCCESS) {
+ if ((type == REG_SZ) || (type ==
REG_EXPAND_SZ)) {
+ if (!ht) {
+ ht =
(HashTable*)malloc(sizeof(HashTable));
+ zend_hash_init(ht, 0,
NULL, ZVAL_INTERNAL_PTR_DTOR, 1);
+ }
+ data =
(zval*)malloc(sizeof(zval));
+ INIT_PZVAL(data);
+ Z_STRVAL_P(data) =
zend_strndup(value, value_len-1);
+ Z_STRLEN_P(data) = value_len-1;
+ zend_hash_update(ht, name,
name_len+1, &data, sizeof(zval*), NULL);
+ }
+ }
+ }
+ if (ht) {
+ if (parent_ht) {
+ HashPosition pos;
+ char *index;
+ uint index_len;
+ ulong num;
+ zval **data;
+
+ for
(zend_hash_internal_pointer_reset_ex(parent_ht, &pos);
+
zend_hash_get_current_data_ex(parent_ht, (void**)&data, &pos) == SUCCESS &&
+
zend_hash_get_current_key_ex(parent_ht, &index, &index_len, &num, 0, &pos) ==
HASH_KEY_IS_STRING;
+
zend_hash_move_forward_ex(parent_ht, &pos)) {
+ if (zend_hash_add(ht, index,
index_len, data, sizeof(zval*), NULL) == SUCCESS) {
+ (*data)->refcount++;
+ }
+ }
+ }
+ zend_hash_update(directories, path, path_len+1,
&ht, sizeof(HashTable*), NULL);
+ ret = 1;
+ }
+
+ efree(name);
+ efree(value);
+ }
+
+ if (ht == NULL) {
+ ht = parent_ht;
+ }
+
+ if (keys) {
+ DWORD i;
+ char *name = (char*)emalloc(max_key+1);
+ char *new_path = (char*)emalloc(path_len+max_key+2);
+ DWORD name_len;
+ FILETIME t;
+ HKEY subkey;
+
+ for (i = 0; i < keys; i++) {
+ name_len = max_key+1;
+ if (RegEnumKeyEx(key, i, name, &name_len, NULL,
NULL, NULL, &t) == ERROR_SUCCESS) {
+ if (RegOpenKeyEx(key, name, 0,
KEY_READ, &subkey) == ERROR_SUCCESS) {
+ if (path_len) {
+ memcpy(new_path, path,
path_len);
+ new_path[path_len] =
'/';
+ path_len++;
+ }
+ memcpy(new_path+path_len, name,
name_len+1);
+ zend_str_tolower(new_path,
path_len+name_len);
+ if (LoadDirectory(directories,
subkey, new_path, path_len+name_len, ht)) {
+ ret = 1;
+ }
+ RegCloseKey(subkey);
+ }
+ }
+ }
+ efree(new_path);
+ efree(name);
+ }
+ }
+ return ret;
+}
+
+static void delete_internal_hashtable(void *data)
+{
+ zend_hash_destroy(*(HashTable**)data);
+ free(*(HashTable**)data);
+}
+
+#define RegNotifyFlags (REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES
| REG_NOTIFY_CHANGE_LAST_SET)
+
void UpdateIniFromRegistry(char *path TSRMLS_DC)
{
char *p, *orig_path;
- HKEY MainKey;
- char *strtok_buf = NULL;
+ int path_len;
+ HashTable **pht;
- if (!OpenPhpRegistryKey("\\Per Directory Values", &MainKey)) {
+ if (!PW32G(registry_directories)) {
+ PW32G(registry_directories) =
(HashTable*)malloc(sizeof(HashTable));
+ zend_hash_init(PW32G(registry_directories), 0, NULL,
delete_internal_hashtable, 1);
+ if (!OpenPhpRegistryKey("\\Per Directory Values",
&PW32G(registry_key))) {
+ PW32G(registry_key) = NULL;
+ return;
+ }
+ PW32G(registry_event) = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (PW32G(registry_event)) {
+ RegNotifyChangeKeyValue(PW32G(registry_key), TRUE,
RegNotifyFlags, PW32G(registry_event), TRUE);
+ }
+ if (!LoadDirectory(PW32G(registry_directories),
PW32G(registry_key), "", 0, NULL)) {
+ return;
+ }
+ } else if (PW32G(registry_event) &&
WaitForSingleObject(PW32G(registry_event), 0) == WAIT_OBJECT_0) {
+ RegNotifyChangeKeyValue(PW32G(registry_key), TRUE,
RegNotifyFlags, PW32G(registry_event), TRUE);
+ zend_hash_clean(PW32G(registry_directories));
+ if (!LoadDirectory(PW32G(registry_directories),
PW32G(registry_key), "", 0, NULL)) {
+ return;
+ }
+ } else if (zend_hash_num_elements(PW32G(registry_directories)) == 0) {
return;
}
@@ -101,48 +224,39 @@
}
}
-
- path = p = php_strtok_r(path, "\\/", &strtok_buf);
-
- while (p) {
- HKEY hKey;
- DWORD lType;
- DWORD values = 0, max_name = 0, max_value = 0, i = 0;
-
- if (p>path) {
- *(p-1) = '\\'; /* restore the slash */
+ path_len = 0;
+ while (path[path_len] != 0) {
+ if (path[path_len] == '\\') {
+ path[path_len] = '/';
}
-
- if (RegOpenKeyEx(MainKey, path, 0, KEY_READ,
&hKey)!=ERROR_SUCCESS) {
+ path_len++;
+ }
+ zend_str_tolower(path, path_len);
+ while (path_len >= 0) {
+ if (zend_hash_find(PW32G(registry_directories), path,
path_len+1, (void**)&pht) == SUCCESS) {
+ HashTable *ht = *pht;
+ HashPosition pos;
+ char *index;
+ uint index_len;
+ ulong num;
+ zval **data;
+
+ for (zend_hash_internal_pointer_reset_ex(ht, &pos);
+ zend_hash_get_current_data_ex(ht, (void**)&data,
&pos) == SUCCESS &&
+ zend_hash_get_current_key_ex(ht, &index,
&index_len, &num, 0, &pos) == HASH_KEY_IS_STRING;
+ zend_hash_move_forward_ex(ht, &pos)) {
+ zend_alter_ini_entry(index, index_len,
Z_STRVAL_PP(data), Z_STRLEN_PP(data), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+ }
break;
}
-
- if(RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
&values, &max_name, &max_value, NULL, NULL) == ERROR_SUCCESS) {
- LPTSTR namebuf = (LPTSTR)emalloc(max_name + 1);
- PBYTE valuebuf = (PBYTE)emalloc(max_value);
-
- while (i < values) {
- DWORD namebuf_len = max_name + 1;
- DWORD valuebuf_len = max_value;
-
- RegEnumValue(hKey, i, namebuf, &namebuf_len,
NULL, &lType, valuebuf, &valuebuf_len);
-
- if ((lType == REG_SZ) || (lType ==
REG_EXPAND_SZ)) {
- /* valuebuf_len includes trailing 0 */
- zend_alter_ini_entry(namebuf,
namebuf_len + 1, valuebuf, valuebuf_len?valuebuf_len-1:0, PHP_INI_SYSTEM,
PHP_INI_STAGE_ACTIVATE);
- }
-
- i++;
+ if (--path_len > 0) {
+ while (path_len > 0 && path[path_len] != '/') {
+ path_len--;
}
-
- efree(namebuf);
- efree(valuebuf);
}
-
- RegCloseKey(hKey);
- p = php_strtok_r(NULL, "\\/", &strtok_buf);
+ path[path_len] = 0;
}
- RegCloseKey(MainKey);
+
efree(orig_path);
}
http://cvs.php.net/viewvc.cgi/php-src/main/main.c?r1=1.705&r2=1.706&diff_format=u
Index: php-src/main/main.c
diff -u php-src/main/main.c:1.705 php-src/main/main.c:1.706
--- php-src/main/main.c:1.705 Tue Oct 17 21:54:16 2006
+++ php-src/main/main.c Fri Nov 10 11:42:40 2006
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: main.c,v 1.705 2006/10/17 21:54:16 pollita Exp $ */
+/* $Id: main.c,v 1.706 2006/11/10 11:42:40 dmitry Exp $ */
/* {{{ includes
*/
@@ -1577,7 +1577,7 @@
ts_allocate_id(&core_globals_id, sizeof(php_core_globals),
(ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor);
core_globals = ts_resource(core_globals_id);
#ifdef PHP_WIN32
- ts_allocate_id(&php_win32_core_globals_id,
sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor,
NULL);
+ ts_allocate_id(&php_win32_core_globals_id,
sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor,
(ts_allocate_dtor) php_win32_core_globals_dtor);
#endif
#endif
EG(bailout) = NULL;
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=1.821&r2=1.822&diff_format=u
Index: php-src/ext/standard/basic_functions.c
diff -u php-src/ext/standard/basic_functions.c:1.821
php-src/ext/standard/basic_functions.c:1.822
--- php-src/ext/standard/basic_functions.c:1.821 Fri Nov 10 09:56:37 2006
+++ php-src/ext/standard/basic_functions.c Fri Nov 10 11:42:40 2006
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: basic_functions.c,v 1.821 2006/11/10 09:56:37 dmitry Exp $ */
+/* $Id: basic_functions.c,v 1.822 2006/11/10 11:42:40 dmitry Exp $ */
#include "php.h"
#include "php_streams.h"
@@ -3950,7 +3950,7 @@
#ifdef ZTS
ts_allocate_id(&basic_globals_id, sizeof(php_basic_globals),
(ts_allocate_ctor) basic_globals_ctor, (ts_allocate_dtor) basic_globals_dtor);
#ifdef PHP_WIN32
- ts_allocate_id(&php_win32_core_globals_id,
sizeof(php_win32_core_globals), (ts_allocate_ctor)php_win32_core_globals_ctor,
NULL);
+ ts_allocate_id(&php_win32_core_globals_id,
sizeof(php_win32_core_globals), (ts_allocate_ctor)php_win32_core_globals_ctor,
(ts_allocate_dtor)php_win32_core_globals_dtor );
#endif
#else
basic_globals_ctor(&basic_globals TSRMLS_CC);
@@ -4073,6 +4073,9 @@
#endif
#else
basic_globals_dtor(&basic_globals TSRMLS_CC);
+#ifdef PHP_WIN32
+ php_win32_core_globals_dtor(&the_php_win32_core_globals TSRMLS_CC);
+#endif
#endif
php_unregister_url_stream_wrapper("php" TSRMLS_CC);
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php