Skip to content

Commit 06332e6

Browse files
committed
introduced DllMain for the main php DLL
The particular need on this is because of the current situation with determining the background functionality for the gettimeofday. DllMain allows to initialize stuff before the DLL can be actually used. Thus, we use different time API on win7 and win8 and later, so the function pointer needs to be initialized before anything in the DLL could even demand it. The change also opens the door for the further optimizations, as now we're able to do the very basic initializations for the whole DLL before it could ever start to live. Fe on this way the TLS initialization could be done, when utilizing the DLL_THREAD_ATTACH/DETACH case. Whether it's really usable in portable way should be synced with other platforms. Be aware that it's dangerous as it possibly causes dead locks. So to use with care. One willing to add items to DllMain should better read the documentation twice and even then try to defer the necessary action.
1 parent 29a91e5 commit 06332e6

File tree

5 files changed

+88
-6
lines changed

5 files changed

+88
-6
lines changed

ext/libxml/libxml.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,7 @@ PHP_LIBXML_API void php_libxml_node_decrement_resource(php_libxml_node_object *o
13411341
}
13421342
/* }}} */
13431343

1344-
#ifdef PHP_WIN32
1344+
#if defined(PHP_WIN32) && defined(COMPILE_DL_LIBXML)
13451345
PHP_LIBXML_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
13461346
{
13471347
return xmlDllMain(hinstDLL, fdwReason, lpvReserved);

win32/build/config.w32

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ ADD_SOURCES("main/streams", "streams.c cast.c memory.c filter.c plain_wrapper.c
159159
userspace.c transports.c xp_socket.c mmap.c glob_wrapper.c");
160160
ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
161161

162-
ADD_SOURCES("win32", "glob.c readdir.c \
162+
ADD_SOURCES("win32", "dllmain.c glob.c readdir.c \
163163
registry.c select.c sendmail.c time.c winutil.c wsyslog.c globals.c getrusage.c");
164164

165165
ADD_FLAG("CFLAGS_BD_WIN32", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");

win32/dllmain.c

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| PHP Version 7 |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) 1997-2015 The PHP Group |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 3.01 of the PHP license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.php.net/license/3_01.txt |
11+
| If you did not receive a copy of the PHP license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| [email protected] so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Authors: Anatol Belski <[email protected]> |
16+
+----------------------------------------------------------------------+
17+
*/
18+
19+
#include <config.w32.h>
20+
21+
#include <win32/time.h>
22+
#include <php.h>
23+
24+
#ifdef HAVE_LIBXML
25+
#include <libxml/threads.h>
26+
#endif
27+
28+
/* TODO this file, or part of it, could be machine generated, to
29+
allow extensions and SAPIs adding their own init stuff.
30+
However expected is that MINIT is enough in most cases.
31+
This file is only useful for some really internal stuff,
32+
eq. initializing something before the DLL even is
33+
available to be called. */
34+
35+
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID dummy)
36+
{
37+
BOOL ret = TRUE;
38+
39+
switch (reason)
40+
{
41+
case DLL_PROCESS_ATTACH:
42+
ret = ret && php_win32_init_gettimeofday();
43+
break;
44+
#if 0 /* prepared */
45+
case DLL_PROCESS_DETACH:
46+
/* pass */
47+
break;
48+
49+
case DLL_THREAD_ATTACH:
50+
/* pass */
51+
break;
52+
53+
case DLL_THREAD_DETACH:
54+
/* pass */
55+
break;
56+
#endif
57+
}
58+
59+
#ifdef HAVE_LIBXML
60+
/* This imply that only LIBXML_STATIC_FOR_DLL is supported ATM.
61+
If that changes, this place will need some rework.
62+
TODO Also this should be revisited as no initialization
63+
might be needed for TS build (libxml build with TLS
64+
support. */
65+
ret = ret && xmlDllMain(inst, reason, dummy);
66+
#endif
67+
68+
return ret;
69+
}
70+

win32/time.c

+10-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTi
2929

3030
static MyGetSystemTimeAsFileTime timefunc = NULL;
3131

32+
#ifdef PHP_EXPORTS
3233
static zend_always_inline MyGetSystemTimeAsFileTime get_time_func(void)
3334
{
3435
MyGetSystemTimeAsFileTime timefunc = NULL;
35-
HMODULE hMod = LoadLibrary("kernel32.dll");
36+
HMODULE hMod = GetModuleHandle("kernel32.dll");
3637

3738
if (hMod) {
3839
/* Max possible resolution <1us, win8/server2012 */
@@ -47,15 +48,20 @@ static zend_always_inline MyGetSystemTimeAsFileTime get_time_func(void)
4748
return timefunc;
4849
}
4950

51+
BOOL php_win32_init_gettimeofday(void)
52+
{
53+
timefunc = get_time_func();
54+
55+
return (NULL != timefunc);
56+
}
57+
#endif
58+
5059
static zend_always_inline int getfilesystemtime(struct timeval *tv)
5160
{
5261
FILETIME ft;
5362
unsigned __int64 ff = 0;
5463
ULARGE_INTEGER fft;
5564

56-
if (!timefunc) {
57-
timefunc = get_time_func();
58-
}
5965
timefunc(&ft);
6066

6167
/*

win32/time.h

+6
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,10 @@ PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp );
5252

5353
PHPAPI int usleep(unsigned int useconds);
5454

55+
#ifdef PHP_EXPORTS
56+
/* This symbols are needed only for the DllMain, but should not be exported
57+
or be available when used with PHP binaries. */
58+
BOOL php_win32_init_gettimeofday(void);
59+
#endif
60+
5561
#endif

0 commit comments

Comments
 (0)