To speed up small requests. One thing I come up with is that adding the pool and pid. If pid is different, we should discard the current pool.
getpid() for Linux returns the cached result. That's awesome. How about macOS?
(In reply to Yusuke Suzuki from comment #1) > getpid() for Linux returns the cached result. That's awesome. > How about macOS? Looking through the XNU's code, getpid() has a caching system, thus, actual system call should be rarely called.
If the pid is cached, does it get updated on fork?
(In reply to JF Bastien from comment #3) > If the pid is cached, does it get updated on fork? getpid() in these systems are typically implemented as a wrapper around the actual system call. And it has caching mechanism. And fork() and other calls are also implemented as a wrapper and they correctly update the cache of getpid().
Why is the pid needed? Seriously -- you shouldn't have a persistent cache -- always fetch fresh random bytes. There isn't any issue with fork, as OS X especially makes no guarantees about the ability for a process to continue operating following a fork. E.g. the only completely safe way to use fork on OS X (or bsd in general afaict) is to follow fork with exec. Once exec happens the process is reset so you won't hit the cache again.
(In reply to Oliver Hunt from comment #5) > Why is the pid needed? > > Seriously -- you shouldn't have a persistent cache -- always fetch fresh > random bytes. It is fresh bytes. This issue is not intended to use the random bytes repeatedly. We should pool the random bytes, that is allocated from the OS in a bulk style, to reduce the system calls. context: https://bugs.webkit.org/show_bug.cgi?id=170095#c9 > > There isn't any issue with fork, as OS X especially makes no guarantees > about the ability for a process to continue operating following a fork. E.g. > the only completely safe way to use fork on OS X (or bsd in general afaict) > is to follow fork with exec. Once exec happens the process is reset so you > won't hit the cache again. If we construct the pool, the problem occurs when using the fork. In that case, the completely same pool is shown in the parent and child process, and they start offering the same random values until the pool is exhausted. The easiest way to avoid the above issue is just invalidating the pool when the pool's pid becomes different from the current getpid().
(In reply to Yusuke Suzuki from comment #6) > > If we construct the pool, the problem occurs when using the fork. > In that case, the completely same pool is shown in the parent and child > process, and they start offering the same random values until the pool is > exhausted. > > The easiest way to avoid the above issue is just invalidating the pool when > the pool's pid becomes different from the current getpid(). Sorry, i think you missed the point of what i was saying. You do not need to guarantee flawless behaviour after fork as it isn't safe for an application to continue running after fork() is called. We shouldn't be adding overhead to support an unsafe operation. The spec for fork() literally states that /no/ global api should be considered safe after a call to fork() (in the child process), and that exec() is essentially the only thing that should be done.
(In reply to Oliver Hunt from comment #7) > (In reply to Yusuke Suzuki from comment #6) > > > > > If we construct the pool, the problem occurs when using the fork. > > In that case, the completely same pool is shown in the parent and child > > process, and they start offering the same random values until the pool is > > exhausted. > > > > The easiest way to avoid the above issue is just invalidating the pool when > > the pool's pid becomes different from the current getpid(). > > Sorry, i think you missed the point of what i was saying. > > You do not need to guarantee flawless behaviour after fork as it isn't safe > for an application to continue running after fork() is called. We shouldn't > be adding overhead to support an unsafe operation. The spec for fork() > literally states that /no/ global api should be considered safe after a call > to fork() (in the child process), and that exec() is essentially the only > thing that should be done. Ah, ok, I see. I think, in the case of WTF, it is a bit difficult to consider such applications using fork() & no exec(). So, it sounds OK. (an example application is like Android's zygote. But in WebKit WebProcess etc. we always use spawn() instead of fork().)
(In reply to Yusuke Suzuki from comment #8) > Ah, ok, I see. I think, in the case of WTF, it is a bit difficult to > consider such applications using fork() & no exec(). So, it sounds OK. > (an example application is like Android's zygote. But in WebKit WebProcess > etc. we always use spawn() instead of fork().) I'm unsure what zygote is doing, but the man page for fork() is fairly explicit about it being unsafe to try to continue arbitrarily inside a process after calling fork -- exec (or any equivalent function that reinitialises the process state) needs to be called.
Mmmm good point, it's my fault for suggesting that we need to worry about fork-safety here.