Quite strange thing.

Quite strange thing.

We have simple object that creates TThread descendant, pretty standard stuff (Except maybe SOAP call which it makes). On Execute it calls coInitialize (I believe because of SOAP stuff)

The problem is that on other projects it works like an charm. But in one, the TThread.Synchronize() call fails. Get errors like :

exception class $C000001D with message 'system exception (code 0xc000001d) at 0x0040b2a6

exception class $C0000096 with message 'privileged instruction at 0x0a99fdac

Etc, did not check all. Usually braks at TMonitor.GetEvent - Line -> Result := AtomicCmpExchange(FLockEvent, Event, nil);

Does anyone have faintest idea why this happens

Tried to use TThread.Queue instead, it seems to work, untill shutdown :

exception class $C0000005 with message 'access violation at 0x7f78f463: write of address 0xfbe1a1b0

etc...

And then pretty massive memory leak:

5 - 12 bytes: TObject x 3, Unknown x 2

13 - 20 bytes: TObjectCache x 2, TThreadList x 1, TSparseArray> x 1
21 - 36 bytes: TLightweightEvent x 1, EAccessViolation x 2, Unknown x 1
37 - 52 bytes: TIMESettings x 1, TList x 1
53 - 68 bytes: TObjectCaches x 1, TQueue x 1
69 - 84 bytes: TThreadPool x 1, Unknown x 1

Tee

Comments

  1. Tommi Prami because writing thread-safe synchronisation support code is extremely hard.

    Looking at how many Delphi versions it took to make TMultiReadExclusiveWriteSynchronizer stable, I am not surprised that other bits have their glitches too.

    OmniThreadLibrary (though it still has faults) is so very stable because Primož Gabrijelčič lives and breaths threading code on a daily base, so I'd try that in stead.

    ReplyDelete
  2. Brett Wilton Sorry for the late reply. Generally speaking and somewhat simplified, I have a watch dog that checks for data changes (it can be a timer, or a thread, if it is a dB monitor).

    If it's a timer, it starts a one-shot thread that checks for changes. The one-shot or watch dog thread loads the data that eventually will go to the display.

    Once the data is completely processed, the display data structure is replaced, and a message sent to the UI thread that repaint is needed, which then loads the UI with data from that structure, either partially or completely.

    Preparing the data is the slow bit, while filling the UI, absolutely or virtually, is usually very fast). In some cases, the previous structure is used to do partial UI changes.

    The simplicity of Synchronize is deceptive, and the more complex the UI change, the higher the risk.

    ReplyDelete
  3. Lars Fosdal thanks Lars, its always interesting to hear alternative solutions and methods.

    ReplyDelete

Post a Comment