Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Mar : Re: TIdTCPServer - threads, global data
| Subject: | Re: TIdTCPServer - threads, global data |
| Posted by: | "Martin James" (mjames_falc..@dial.pipex.com) |
| Date: | Thu, 16 Mar 2006 10:36:06 |
> Sending/posting by itself is perfectly safe. The way that Mathjis is
> retreiving the HWND being sent/posted to, on the other hand, is not safe.
> Actually, it is Borland's own code, not Microsoft's, that requires that.
> Microsoft allows the styles of a window to be changed dynamically without
> recreating the HWND.
Whatever <g>
> But Borland does not do that, mainly because it wants
> to be able to apply multiple styles from a single operation. Even when
one
> style is changing, Borland usually recreates the HWND so that all styles
are
> reapplied in bulk, so that a single piece of code can handle them all in a
> single location.
>
> > PostMessage also avoids the twin horrors of:
> >
> > 'TThread.synchronize' (sucks)
> > 'TThread.waitFor' (sucks bad)
>
> There is nothing wrong with those methods (other than the bug that
WaitFor()
> has under D6+ when FreeOnTerminate is True)
We may have to agree to disagree on that one.
> PostMessage(), on the other hand, is not error-free, either. If a message
> fails to be posted,
.. then a user excepton handler can free the object. Failed postings are
only likely if the 10000 queue limit is reached. That is a lot of objects
to start with, even if no other limit is placed on the number of objects
used for inter-thread comms.
or the message queue does not remove all pending
> messages
The only time this is important is if a threaded subSsytem is shut down
during an app run, rather than at app close. I accept that this is an issue
that takes some care/consideration.
> > CM_OBJECTRX=$8FF0;
>
> I highly recomend using RegisterWindowMessage() instead of a constant.
Well, the window handle is unique on the system.
> Also, you are not validating that the received message is genuine before
> using the message's parameters.
If the user posts crap...
> > ThreadPostWindowClass: TWndClass = (
>
> The VCL has an AllocateHWnd() function that handles those details for you.
Yeah, but means calling the VCL during an initializatoin section. I'm never
happy doing this, since I do not know what is going on <g>
> > ThreadPostWindow:=CreateWindow(...
>
> queueObjectToMainThread() is not checking whether CreateWindow() actually
> succeeded or not.
True. The point to check this would be in the initialization code where the
window is created. I should add a check but, if the create fails, the app
is probably in trouble anyway.
> > DestroyWindow(ThreadPostWindow);
>
> You are not setting ThreadPostWindow back to nil, in case another unit
calls
> queueObjectToMainThread() after the unit has been finalized.
This is a shutdown issue again. Threaded subSystems should, ideally, be
shut down before the app closes and the finalizations called. I would
expect that all forms and other controls would be destroyed anyway by the
time finalizations are called.
> Also, the problem with using a dedicated unit to manage the queue is that
> you have to ensure that it gets finalized properly before any threads are
> created,
I think you mean 'initialized properly' <g>. You have to try quite hard to
queue off an object to a TControl descendant before any forms are created.
and that all threads are fully terminated before the unit is
> finalized.
Shutdown issue - already discussed.
Rgds,
Martin
none