Re: Win32 signal code - first try
От | Magnus Hagander |
---|---|
Тема | Re: Win32 signal code - first try |
Дата | |
Msg-id | 6BCB9D8A16AC4241919521715F4D8BCE171590@algol.sollentuna.se обсуждение исходный текст |
Список | pgsql-hackers-win32 |
Most of this lokos really good :-) >1) Named pipe server creates new thread on receipt of signal I'm assuming you read the signal number somewhere in between here? Before the WriteFile, no? >2) New Thread issues WriteFile (thereby immediately informing >the signaller >of the receipt of the signal) [snip] >4) Changes to the current signalling state would simply >PulseEvent(someManualEvent) Please note that the documentation says: Note This function is unreliable and should not be used. It exists mainly for backward compatibility. We might be immune to the problems with it, but we need to check that really carefullyi before using it. I try to stay away from functions like that, since it can come back and bite you later when something is modified :-) >[Note: we'd need to protect the "current signal is blocked" >test with the >existing Critical section (faster, but haven't convinced myself this is >completely safe), or change all the existing crictical section >calls to be >locks/releases on the above "someMutex" (slower, but bulletproof)] What would the problem with the critical section be? It should be just as safe as a mutex only a lot faster. The limitation it has compared to a mutex is that it can only be used between threads in a processes, whereas the mutex exists in the global namespace. The only thing you really can't do with critical sections, AFAIK, is that a thread can only block on one CS at a time. With mutexes, you can use WaitForMultipleObjects() on two mutexes and go with whichever became available first. >However, there is nothing in either my nor your suggestion that guards >against the following race-condition. Essentially, nothing is >stopping the >APC actually being run at some later time (because, as you'll >note, we've >only stopped the queuing of the APC, not the actual execution) when it >should be blocked. > >AFAICS, a simple solution to this exists. Execute a SleepEx(0,TRUE) >(strictly, whatever __pg_poll_signals ends up being) on entry to any >function that changes the current signalling state. That way, we'll >guarantee that our signals will be delivered + executed before >it becomes >unsafe to do so. Sounds like a good solution to me. Here's another idea altogether for the blocking signals (just occured to me, may be seriously flawed, but I figured I should at least get it out there): How about keepnig a bitmask of "queued signals". These are signals that were "fired while blocked". Then at the top of the functions that modify the signal blocking mask, check if there are any queued executions for signals that are currently not blocked (meaning they just became unblocked). (And of course, clear the queue of that signal). Doing this should remove a lot of the complexity from the signal handling threads, since they don't have to stay around until the actual execution of the signal. If a signal is queued twice while blocked, should the handler execute twice once the signal is unblocked? If so, the bitmask would have to be replaced with an array of counters, but the general idea still remains. Thoughs? //Magnus
В списке pgsql-hackers-win32 по дате отправления: