You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently pthreads has some lifetime issues mostly surrounding child-to-parent-thread data passing of stuff like classes and functions. This is largely because of request-local interned strings which are used for basically all user code.
Request-local interned strings behave mostly the same as regular interned strings (they are not refcounted). However, instead of living for the lifespan of the PHP process like permanent interned strings do, they only live until the end of the current request. In the context of pthreads, a request == a thread.
This has manifested in problems with Threaded object connections when passing Threaded objects from a child thread to a parent thread which doesn't know about the object's class. It assumes that because IS_STR_INTERNED is set on the GC flags, it's safe to use the strings in the class without copying them, but this isn't true, because they might be destroyed when the creating thread exits if they are request-local.
This has been worked around by hard-copying interned strings in some cases, but it's still not a very good solution, because in the cases where strings are not hard copied, there's an assumption about the origin context's lifetime, which imposes various restrictions (for example, it's not practical to support pthread_detach().)
The solution to this problem is to do something similar to OPcache, and implement a custom thread-safe interned strings buffer. We can assign custom handlers to create request-local interned strings in such a way that they'll persist until the process end, making them safe to reuse unconditionally.
In addition it's my belief that a custom interned string request handler can drastically reduce the memory usage of classes autoloaded onto other threads, since they can be looked up in an existing table instead of allocated for each thread.
Since 8.1, we're no longer able to reuse request-local interned strings, due to CE_CACHE, so interned strings are always hard-copied unless IS_STR_PERMANENT is used. We do now have a thread-safe interned strings buffer, but it's currently only used for property names.
Currently pthreads has some lifetime issues mostly surrounding child-to-parent-thread data passing of stuff like classes and functions. This is largely because of request-local interned strings which are used for basically all user code.
Request-local interned strings behave mostly the same as regular interned strings (they are not refcounted). However, instead of living for the lifespan of the PHP process like permanent interned strings do, they only live until the end of the current request. In the context of pthreads, a request == a thread.
This has manifested in problems with Threaded object connections when passing Threaded objects from a child thread to a parent thread which doesn't know about the object's class. It assumes that because IS_STR_INTERNED is set on the GC flags, it's safe to use the strings in the class without copying them, but this isn't true, because they might be destroyed when the creating thread exits if they are request-local.
This has been worked around by hard-copying interned strings in some cases, but it's still not a very good solution, because in the cases where strings are not hard copied, there's an assumption about the origin context's lifetime, which imposes various restrictions (for example, it's not practical to support pthread_detach().)
The solution to this problem is to do something similar to OPcache, and implement a custom thread-safe interned strings buffer. We can assign custom handlers to create request-local interned strings in such a way that they'll persist until the process end, making them safe to reuse unconditionally.
https://github.com/php/php-src/blob/a1fee87c9a8a6ed58f2a8270c0a9e61a674d32db/ext/opcache/ZendAccelerator.c#L2686
The text was updated successfully, but these errors were encountered: