Recent

Author Topic: paint called during paintlock in custom SynEdit  (Read 2845 times)

Pascal

  • Hero Member
  • *****
  • Posts: 932
paint called during paintlock in custom SynEdit
« on: January 21, 2017, 07:18:36 am »
Martin, i have some trouble with a custom SynEdit i've build!
My goal is to build a multithreaded tokenizer and parser for Cobol
My decendant of TCustomSynEdit registers 3 handlers:
Code: Pascal  [Select][+][-]
  1.     procedure LineCountChanged(Sender: TSynEditStrings; pIndex, pCount: Integer);
  2.     procedure BeforeLineCountChanged(Sender: TSynEditStrings);
  3.     procedure LinesModified(Sender: TSynEditStrings; pIndex, pNewCount, pOldCount: Integer);
  4.  
To have BeforeLineCountChanged, i modified SynEdit to notify before the line count is going to change
so that i can stop/interrupt all threads that are working on FLines (tokenizer, parser) before the lines get deleted.
In LinesModified i start the theads on the changed range (and first evantualy continue an interrupted range)
LineCountChanged modifies the range of the eventualy stopped tokenizer thread
This works as expected!
The problem i get some times is that i get the error output: paint called during paintlock. This happens the first time
when i call Lines.LoadFormFile. I am not aware of any calls to painting related things while i am in the notify handlers.

How can i fix this?

I can send you the project and the patches to SynEdit, if you wish to.

Regards
Pascal

laz trunk x64 - fpc trunk i386 (cross x64) - Windows 10 Pro x64 (21H2)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9874
  • Debugger - SynEdit - and more
    • wiki
Re: paint called during paintlock in custom SynEdit
« Reply #1 on: January 21, 2017, 04:09:13 pm »
This may be hard to debug....

Where you able to get a stacktrace, with symbols?
I am not sure I have time to go through your sources....

But to start, here is what I would do in debugging>
Either
1) (slow)
set a breakpoint (properties, do NOT break but take a snapshot) in begin/end update.  (and other places, if any, that get the lock)
Then when it happen, open debug history, and check for who got the paintlock.
(leave the stack window open, while taking snapsots, and you will get more than 5 lines of stack per snap)
2) the same, but use debugln
if you add debugln at the caller level, then you need no trace.

Also, assuming that you eventually call EndUpdate you should get
Code: Pascal  [Select][+][-]
  1.         debugln('Returning from Paintlock, wich had Paint called while active');
  2.         DumpStack;
  3.  
But those checks are not complete, if there are furthe BeginPaintlock before that, then they may not happen. You need to add guards to all other write access to FInvalidateRect.
(for that -using ifdef- you can send the patch / may be helpful for others too).

----------------------
You can also add flags when your threads are working, and catch calls to BeginUpdate....
(or use breakpoints, that will enable/disable other breakpoint... but that is slower and more work)




 

TinyPortal © 2005-2018