Some blurb about gtk+ integration pain: * gtk+ ** main-loop + The first thread to the main-loop gets to lurk in the 'select' - any other thread gets to block on that. + Not a problem, since all timeout adds etc. interrupt the existing mainloop. + Lock state in the filter_function: + gdk_event_translate: lock must be held when called + lock taken without notifying SalYieldMutex::acquire + we must setup SalYieldMutex / and tear-down too. !? + How do gtk+ inferior loops work ? + we need to be able to hook into the take/drop semantics of the inferior loop really. + What happens when gtk+ drops it's lock ? + doesn't happen except around the main-loop / event emission. + thus - setup the lock during the duration of the event emission. + URGH- gmain.c holds the context (not released) over dispatch thus no other thread can get into the mainloop, until the round of dispatch is over ... [!] - the same is true of VCL. * vcl + we drop our lock as we poll + we then re-take any locks & re-poll with the guard taken. + cf. saldata.hxx's YieldMutexReleaser. + we do not XInitThreads ... + we guard XNextEvent etc. with the YieldMutex + cf. vcl/unx/source/app/saldisp.cxx (Yield) from + vcl/unx/source/app/saldata.cxx (Yield) + vcl/source/app/svapp.cxx (Application::Yield): -> SalInstance::Yield -> GetSalData()->GetLib()->Yield( bWait ); SalInstance::AcquireYieldMutex - called by: Application::AcquireSolarMutex + Need to bin all daft direct uses of mpSalYieldMutex; ** Solar Mutex == YieldMutex cf. Application::GetSolarMutex -> GetYieldMutex. also cf. Application::GetMainThreadIdentifier ** Recursive lock <-> non recursive impl. + need a slave lock to handle ThreadId changes etc. + need to preserve 'Count' after a drop/pick-up restoration [!] lock A -> lock B -> unlock A lock A -> unlock B -> unlock A A race condition ! ** Conditions: L - locked, U - unlocked Gdk YM ID cnt An unowned lock: lock: N N 0 0 N Y ME 1 - other lockers inhibited ... N N ME 1 - a yield/busy loop for other lockers ? Y N ME 1 unlock: Y N ME 1 Y Y 0 0 Y N 0 0 N N 0 0 Forget the lock - imagine the lock is a queue - push/pop or somesuch, we have to efficiently synchronize access to it.