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

Reply via email to