View Issue Details

IDProjectCategoryView StatusLast Update
0010158LazarusWidgetsetpublic2013-09-03 12:08
ReporterSergey Marchenko Assigned ToFelipe Monteiro de Carvalho  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Fixed in Version0.9.25 (SVN) 
Summary0010158: Method Synchronize of TThread class doesn't work under WinCE
DescriptionMethod Synchronize of TThread class doesn't work under WinCE
TagsNo tags attached.
Fixed in Revision13117
LazTarget1.4
WidgetsetWinCE
Attached Files

Activities

Yuriy Sydorov

2007-11-13 19:34

developer   ~0016122

Works for me with fpc 2.2.0:

{$apptype console}

uses
  classes, windows;

type
  TMyThread = class(TThread)
  private
    procedure DoTest;
  protected
    procedure Execute; override;
  end;

{ TMyThread }

procedure TMyThread.DoTest;
begin
  writeln('Synchronized. ProcessId=',GetCurrentThreadId);
end;

procedure TMyThread.Execute;
var
  i: integer;
begin
  writeln('Thread started. ProcessId=',GetCurrentThreadId);
  for i:=1 to 3 do begin
    Synchronize(DoTest);
    Sleep(1000);
  end;
end;

begin
  writeln('Main thread. ProcessId=',GetCurrentThreadId);
  with TMyThread.Create(True) do begin
    FreeOnTerminate:=True;
    Resume;
    WaitFor;
  end;
  writeln('All done.');
end.

2007-11-15 09:33

 

multithreadingTest.zip (57,227 bytes)

Sergey Marchenko

2007-11-15 16:57

reporter   ~0016168

I have attached example of test project that works fine under Win32 but refuses to work under WinCE. This project is almost equal to another one that comes with every release of Lazarus (..\examples\multithreading\multithreadingexample1.lpr). The only difference is that the original project modifies caption of main form and my project modifies caption of TLabel component.
Currently I'm using fpc 2.2.0 and Lazarus snapshot from the 7th of November 2007.

Yuriy Sydorov

2007-11-15 19:51

developer   ~0016173

This is Lazarus LCL issues, not FPC. LCL for wince does setup Synchronize support properly...

Felipe Monteiro de Carvalho

2007-11-15 20:42

developer   ~0016175

How is synchronize support set up?

Yuriy Sydorov

2007-11-15 21:52

developer   ~0016179

It is needed to assign WakeMainThread handler and post message to main GUI thread to notify about synchronize. Then call CheckSynchronize in main GUI thread in response to that message.
Look at win32 LCL implementation. Maybe it is implemented differently.

Sergey Marchenko

2007-11-19 07:18

reporter   ~0016215

I have decided to explore lcl wince source files and found something interesting. "..\lcl\interfaces\wince\winceobject.inc" contains following lines of code:

  //roozbeh:what is this?!!
  // Thread.Synchronize support
  //WakeMainThread := @HandleWakeMainThread;

It looks like "HandleWakeMainThread" method was not implemented for some reasons. That's why this code was commented and "Synchronize" method doesn't work.

Felipe Monteiro de Carvalho

2007-11-24 19:21

developer   ~0016348

I did a trivial implementation. Please test.

Christian

2007-11-24 23:48

reporter   ~0016355

Last edited: 2007-11-24 23:49

Dont work here for me. Tested with an simple Thread that reads data from the Serial Port

Sergey Marchenko

2007-11-26 09:23

reporter   ~0016377

Hi Felipe!

Do your changes exist in Lazarus snapshot from 25/11 ?

Christian

2007-11-26 13:17

reporter   ~0016381

Yes the snapshots are build every day and the changes are from 11/24

Sergey Marchenko

2007-11-26 13:59

reporter   ~0016382

Felipe, I have downloaded Lazarus snapshot from 26/11. I have found, that you've made "WakeMainThread" assignment in "winceobject.inc" and implemented "HandleWakeMainThread" method. Unfortunately I have not yet checked whether this will cause my code work or not. Anyway, thank you for your cooperation. But one question interests me very much. Can you tell me, where exactly the "WM_NULL" message is processed? I can't find this place in source codes.

Sergey Marchenko

2007-11-27 09:48

reporter   ~0016397

Yes, unfortunately Christian is right. "Synchronize" still doesn't work.

Felipe Monteiro de Carvalho

2007-11-27 10:37

developer   ~0016401

To find where something is declared or used just do a Find in Files, with lcl/interfaces/wince as directory

However I can already say there is no place where WM_NULL is processed, at least directly, and also not on the win32 interface.

All kinds of messages are handled on wincecallback.inc, but I don't know if there is anything related to this there.

I did also a search to synchronize to try to get comments about this but there isn't much.

There are some small differences between procedure TWinCEWidgetSet.AppProcessMessages; and the equivalent win32 one, maybe they are the cause, but that is just a guess.

Sergey Marchenko

2007-11-27 12:31

reporter   ~0016411

Last edited: 2007-11-27 12:34

Felipe, thank you for answer. I'll try to fix problem with "synchronize" myself next weekend.

Sergey Marchenko

2007-11-28 10:15

reporter   ~0016438

Last edited: 2007-11-28 11:01

Due to my impatience :) , I have decided not to wait till weekend.
So ... I've found two ways to solve the problem being discussed.

The first one.

It's required to add handler for WM_NULL message in "wincecallback.inc" in WindowProc function. Something like this:

WM_NULL : CheckSynchronize;

I've put it above handler for WM_ACTIVATE message. In this case we get fully message driven mechanism for "Synchronize" processing. Also, there is no need for code in "winceobject.inc"->"TWinCEWidgetSet.AppProcessMessages" that tries to call CheckSynchronize. At least because it never executes now.

The second way for "Synchronize" revival.

We have to move the part of "if ... then ... else" construction that is responsible for synchronize a little bit upper. So the "TWinCEWidgetSet.AppProcessMessages" method should look like this:

============================================================================

procedure TWinCEWidgetSet.AppProcessMessages;
var
  AMessage: TMsg;
  AccelTable: HACCEL;
  retVal, index: dword;
  
Begin
  repeat
{$ifdef DEBUG_ASYNCEVENTS}
    if Length(FWaitHandles) > 0 then
      DebugLn('[ProcessMessages] WaitHandleCount=', IntToStr(FWaitHandleCount),
        ', WaitHandle[0]=', IntToHex(FWaitHandles[0], 8));
{$endif}
    retVal := Windows.MsgWaitForMultipleObjects(FWaitHandleCount,
      FWaitHandles[0], false, 0, QS_ALLINPUT);

    if retVal = WAIT_TIMEOUT then
    begin
      // check for pending to-be synchronized methods
      CheckSynchronize;
      CheckPipeEvents;
    end;

    //roozbeh:added
    if FWaitHandleCount = 0 then
      retVal := WAIT_OBJECT_0;

    if (WAIT_OBJECT_0 <= retVal) and (retVal < WAIT_OBJECT_0 + FWaitHandleCount) then
    begin
      index := retVal-WAIT_OBJECT_0;
      FWaitHandlers[index].OnEvent(FWaitHandlers[index].UserData, 0);
      
    end else
    if retVal = WAIT_OBJECT_0 + FWaitHandleCount then
    begin
      while PeekMessage(AMessage, HWnd(Nil), 0, 0,PM_REMOVE) do
      begin
        AccelTable := GetWindowInfo(AMessage.HWnd)^.Accel;
        if (AccelTable = HACCEL(nil))
          or (TranslateAccelerator(AMessage.HWnd, AccelTable, @AMessage) = 0) then
        begin
          TranslateMessage(@AMessage);
          DispatchMessage(@AMessage);
        end;
      end;

    if FWaitHandleCount = 0 then
     break;

    end
    else
    if retVal = $FFFFFFFF then
    begin
      DebugLn('[TWinCEWidgetSet.AppProcessMessages] MsgWaitForMultipleObjects returned: ', IntToStr(GetLastError));
      break;
    end;
  until false;
End;

============================================================================

In this case there is no need in assigning of WakeMainThread variable and HandleWakeMainThread method, because "synchronize" mechanism is not message driven.

Both solutions have been tested by me and work fine. All we have to do is to decide, which one to apply.

Felipe Monteiro de Carvalho

2007-11-28 11:20

developer   ~0016440

I prefer the message handling mechanism. It seams easier to understand, and a little more elegant. Please also clean AppProcessMessages on the patch.

I don't know why the win32 interface went with the second while still partially implementing the first ... maybe a long forgotten ToDo.

2007-11-30 12:36

 

winceobject.patch (534 bytes)   
*** winceobject.inc	Sat Nov 24 19:21:18 2007
--- winceobject.inc.new	Thu Nov 29 12:17:34 2007
***************
*** 328,340 ****
  
      end
      else
-     if retVal = WAIT_TIMEOUT then
-     begin
-       // check for pending to-be synchronized methods
-       CheckSynchronize;
-       CheckPipeEvents;
-       break;
-     end else
      if retVal = $FFFFFFFF then
      begin
        DebugLn('[TWinCEWidgetSet.AppProcessMessages] MsgWaitForMultipleObjects returned: ', IntToStr(GetLastError));
--- 328,333 ----
winceobject.patch (534 bytes)   

2007-11-30 12:36

 

wincecallback.patch (536 bytes)   
*** wincecallback.inc	Tue May 29 20:27:36 2007
--- wincecallback.inc.new	Fri Nov 30 14:32:17 2007
***************
*** 985,990 ****
--- 985,995 ----
  //  Assert(False, Format('Trace:WindowProc - Window Value: $%S-%d; Msg Value: %S; WParam: $%S; LParam: $%S', [IntToHex(Window, 4), Window, WM_To_String(Msg), IntToHex(WParam, 4), IntToHex(LParam, 4)]));
  
    Case Msg Of
+     WM_NULL:
+     Begin
+       CheckSynchronize;
+       CheckPipeEvents;
+     End; 
      WM_ACTIVATE:
      Begin
        Case Lo(WParam) Of
wincecallback.patch (536 bytes)   

Sergey Marchenko

2007-11-30 12:37

reporter   ~0016481

Patches for wincecallback.inc and winceobject.inc uploaded.

Felipe Monteiro de Carvalho

2007-12-02 10:05

developer   ~0016528

Thanks, applied.

I had to change

    WM_NULL:
      .....
      CheckPipeEvents;

to

    WM_NULL:
      .....
      TWinCEWidgetset(Widgetset).CheckPipeEvents;

to make it compile

Issue History

Date Modified Username Field Change
2007-11-12 12:54 Sergey Marchenko New Issue
2007-11-12 14:35 Yuriy Sydorov Status new => assigned
2007-11-12 14:35 Yuriy Sydorov Assigned To => Yuriy Sydorov
2007-11-13 19:34 Yuriy Sydorov Note Added: 0016122
2007-11-13 19:34 Yuriy Sydorov FPCTarget => -
2007-11-13 19:34 Yuriy Sydorov Status assigned => feedback
2007-11-15 09:33 Sergey Marchenko File Added: multithreadingTest.zip
2007-11-15 16:57 Sergey Marchenko Note Added: 0016168
2007-11-15 19:48 Yuriy Sydorov Project FPC => Lazarus
2007-11-15 19:49 Yuriy Sydorov Assigned To Yuriy Sydorov =>
2007-11-15 19:50 Yuriy Sydorov LazTarget => -
2007-11-15 19:51 Yuriy Sydorov Note Added: 0016173
2007-11-15 19:51 Yuriy Sydorov Status feedback => new
2007-11-15 20:42 Felipe Monteiro de Carvalho Note Added: 0016175
2007-11-15 21:52 Yuriy Sydorov Note Added: 0016179
2007-11-17 12:09 Felipe Monteiro de Carvalho LazTarget - => post 1.2
2007-11-17 12:09 Felipe Monteiro de Carvalho Status new => acknowledged
2007-11-19 07:18 Sergey Marchenko Note Added: 0016215
2007-11-19 07:33 Felipe Monteiro de Carvalho Status acknowledged => assigned
2007-11-19 07:33 Felipe Monteiro de Carvalho Assigned To => Felipe Monteiro de Carvalho
2007-11-24 19:21 Felipe Monteiro de Carvalho Note Added: 0016348
2007-11-24 23:48 Christian Note Added: 0016355
2007-11-24 23:49 Christian Note Edited: 0016355
2007-11-26 09:23 Sergey Marchenko Note Added: 0016377
2007-11-26 13:17 Christian Note Added: 0016381
2007-11-26 13:59 Sergey Marchenko Note Added: 0016382
2007-11-27 09:48 Sergey Marchenko Note Added: 0016397
2007-11-27 10:37 Felipe Monteiro de Carvalho Note Added: 0016401
2007-11-27 12:31 Sergey Marchenko Note Added: 0016411
2007-11-27 12:33 Sergey Marchenko Note Edited: 0016411
2007-11-27 12:34 Sergey Marchenko Note Edited: 0016411
2007-11-28 10:15 Sergey Marchenko Note Added: 0016438
2007-11-28 10:16 Sergey Marchenko Note Edited: 0016438
2007-11-28 11:01 Sergey Marchenko Note Edited: 0016438
2007-11-28 11:20 Felipe Monteiro de Carvalho Note Added: 0016440
2007-11-30 12:36 Sergey Marchenko File Added: winceobject.patch
2007-11-30 12:36 Sergey Marchenko File Added: wincecallback.patch
2007-11-30 12:37 Sergey Marchenko Note Added: 0016481
2007-12-02 10:05 Felipe Monteiro de Carvalho Fixed in Revision => 13117
2007-12-02 10:05 Felipe Monteiro de Carvalho Widgetset => WinCE
2007-12-02 10:05 Felipe Monteiro de Carvalho Status assigned => resolved
2007-12-02 10:05 Felipe Monteiro de Carvalho Fixed in Version => 0.9.25 (SVN)
2007-12-02 10:05 Felipe Monteiro de Carvalho Resolution open => fixed
2007-12-02 10:05 Felipe Monteiro de Carvalho Note Added: 0016528
2008-03-29 12:18 Marc Weustink Status resolved => closed
2008-04-21 09:17 Vincent Snijders Category FCL => Widgetset
2008-04-21 09:17 Vincent Snijders Product Version 2.2.0 =>
2013-09-03 12:08 Martin Friebe LazTarget post 1.2 => 1.4