Hi Stas,
SF>>Attached are patches for fixing the win32/ZTS thing only when needed -
SF>>this will _only_ work if you apply Dmitry's patch to 5_2 as well. The
SF>>idea being that this way everybody's covered.
I'm not sure I understand what this line does:
ts_free_id(table_size - zend_dl_module_count());
Can you explain?
OK, grab a coffee...
zend_dl_module_count() counts the modules as they enter module_destructor().
(Remember that dl'd modules are of necessity loaded last of all, and that
shutdown is in direct reverse order of loading.)
The number of the final TSRM resource id that was loaded will be the size of
the table they're stored in, plus one (to keep life simple). So we pick up
that figure and call it 'table_size'. Then we subtract the number of modules
registered in the dl_module_count.
That's actually the only way to figure out the resource id for any given
module without storing it in the module itself (which this patch checks for,
in terms of Dmitry's patch - I'm not altogether clear on what his does at
this point but they'll need to avoid each other).
You can't store the id during startup because there are resource ids that
are _not_ modules further down in the list and there's no way to know how
many of those there are, so you'll get up to about 12 with internal modules
and then suddenly the next number you can pick up is 20-something and static
because all the resource id's were already allocated before the module
registry kicked in.
Since dynamically loaded modules are the last ones to load, they're the
first to unload. They're checked for a handle, and if they have one they're
dl'd and we need to free the resource before unloading the module. We _only_
care about dl'd modules at this point. Nothing else actually needs its
resource freeing before tsrm_shutdown() (which cleans up everything that
wasn't freed already and is totally independent of this bit of maths), and
nothing else is touched in that way.
Anything may call ts_free_id() in its own right from its own source, but it
will have a known ID in that case anyway (so not an issue) and I added a
check to prevent double calls there, mainly because several extensions have
it currently.
This id generation is not 100% foolproof, sure - for example ext/gd doesn't
have any dealings with TSRM at all, and there's no way to know about that
from the data the module carries, so when it comes through as a shared
module it actually frees the resources for the next module in the shutdown
list. But freeing a module's resources slightly early during shutdown
doesn't do it any harm anyway - and the big thing here's to guarantee the
resources are freed before any module's unloaded, which this does because it
starts from the top, and to make sure you don't attempt to free a
non-existent resource id, which this also does because it can't touch
anything very far down in the shutdown list.
- Steph
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php