Wrapper class for thread-safe objects - delphi

I have recently played around with one demo opensource project for the basic functionality of the INDY10 TCP/IP server and stumbled upon the problem of internal multitasking implementation of INDY and its interaction with VCL components. Since there are many different topics in SO on the subject, I decided to make a simple client-server application and test some of the solutions and approaches suggested, at least the ones that I understood correctly. Below I would like to summarize and review an approach that was previously suggested on SO, and if possible listen to your expert opinion on the subject.
Problem: Encapsulation the VCL for thread-safe usage inside an indy10-based client/server application.
Description of the Development Env.:
Delphi Version: Delphi® XE2 Version 16.0
INDY Version 10.5.8.0
O.S. Windows 7 (32Bit)
As mentioned in the article ([ Is the VCL Thread-safe?]) (sorry I do not have enough reputation to post the link) special care should be taken when one wishes to use any kind of VCL components inside a multithreaded (multitasking) application. VCL is not thread safe, but can be used in a thread safe way!
The how and the why usually depend on the application at hand but one can attempt to generalize a bit and suggest some kind of general approach to this problem. First of all, as in the case of INDY10, one does not need to be explicitly parallelizing his code, i.e. create and execute multiple threads, in order to expose VCL to deadlocks and data inter dependencies.
In every sclient-server application, the server has to be able to handle multiple requests simultaneously, so naturally, INDY10 internally implements this functionality. This would mean that the INDY10 set of classes are responsible to manage the program's thread creation, execution and destruction procedures internally.
The most obvious place where our code is exposed to the inner workings of INDY10 and hence possible thread conflicts, is the IdTCPServerExecute (TIdTCPServer onExecute event) method.
Naturally, INDY10 provides classes (wrappers) that ensure thread-safe program flow, but since I did not manage to get enough explanation on their application and usage, I prefer a custom made approach.
Below I summarize a method ( the suggested technique is based on a previous comment I found in SO How to use TIdThreadSafe class from Indy10 ) that attempts (and presumably succeeds) in dealing with this problem:
The question I tackle below is: How to make a specific class "MyClass" ThreadSafe?
The main idea is to create kind of a wrapper class that encapsulates "MyClass" and queues the threads that try to access it in First-In-First-Out principle. The underlying objects that are used for synchronization are [Windows's Critical Section Objects.].
In the context of a client-server application, "MyClass" will contain all thread unsafe functionality of our server, so we will try to ensure that those procedures and functions are not executed by more than one working thread simultaneously. This naturally means loss of parallelism of our code, but since the approach is simple and seems to be , in some cases this maybe a useful approach.
Wrapper class Implementation:
constructor TThreadSafeObject<T>.Create(originalObject: T);
begin
tsObject := originalObject; // pass it already instantiated instance of MyClass
tsCriticalSection:= TCriticalSection.Create; // Critical section Object
end;
destructor TThreadSafeObject<T>.Destroy();
begin
FreeAndNil(tsObject);
FreeAndNil(tsCriticalSection);
inherited Destroy;
end;
function TThreadSafeObject<T>.Lock(): T;
begin
tsCriticalSection.Enter;
result:=tsObject;
end;
procedure TThreadSafeObject<T>.Unlock();
begin
tsCriticalSection.Leave;
end;
procedure TThreadSafeObject<T>.FreeOwnership();
begin
FreeAndNil(tsObject);
FreeAndNil(tsCriticalSection);
end;
MyClass Definition:
MyClass = class
public
procedure drawRandomBitmap(abitmap: TBitmap); //Draw Random Lines on TCanvas
function decToBin(i: LongInt): String; //convert decimal number to Bin.
procedure addLineToMemo(aLine: String; MemoFld: TMemo); // output message to TMemo
function randomColor(): TColor;
end;
Usage:
Since threads execute in order and wait for the thread which has the current ownership of the critical section to finish (tsCriticalSection.Enter; and tsCriticalSection.Leave;) it is logical that if you want to manage that ownership relay, you need one unique instance TThreadSafeObject (you can consider using the singleton pattern). so include:
tsMyclass:= TThreadSafeObject<MyClass>.Create(MyClass.Create);
in Form.Create and
tsMyclass.Destroy;
in Form.Close; Here tsMyclass is a global variable of type MyClass.
Usage:
Regarding the usage of MyClass try the following:
with tsMyclass.Lock do
try
addLineToMemo('MemoLine1', Memo1);
addLineToMemo('MemoLine2', Memo1);
addLineToMemo('MemoLine3', Memo1);
finally
// release ownership
tsMyclass.unlock;
end;
, where Memo1 is an instance of a TMemo component on the form.
With this, we are supposed to ensure that anything that happens when tsMyClass is locked
will be executed by only one thread at a time. An obvious drawback of this approach, however, is that since I have only one instance of tsMyclass, even if one thread is trying to draw for e.g. on the Canvas, while another is writing on the Memo, the first thread will have to wait for the second to finish and only then it will be able to carry out its job.
My questions here are:
Is the above suggested method correct? Am I still free of race
conditions or do I have some "loopholes" in the code, from where
data conflicts could occur?
How can one, in general, test for thread
unsafety of his/her applicaiton?
I would like to stress that the above approach is in no way my own doing. It is basically a summary of the solution found in 2. Nevertheless, I have decided to post again in an attempt to get some kind of closure on the topic or a kind of proof of validity for the suggested solution. Besides, repetition is mother of all knowledge, as they say.

With this, we are supposed to ensure that anything that happens when
tsMyClass is locked will be executed by only one thread at a time. An
obvious drawback of this approach, however, is that since I have only
one instance of tsMyclass, even if one thread is trying to draw for
e.g. on the Canvas, while another is writing on the Memo, the first
thread will have to wait for the second to finish and only then it
will be able to carry out its job.
I see one big problem here: the VCL (forms, drawing, etc...) lives on the main thread. Even if you block concurrent thread access, the updates need to be done in the context of the main thread. This is the part where you need to use Synhronize(), the big difference with a lock (Criticalsection) is that synchronized code is ran in the context of the main thread. The end result is basically the same, your threaded code is serialized and you lose the advantage of using threads in the first place.

Locking on the whole object can be much too coarse.
Imagine cases where some properties or methods are independent of others. If the lock works on a "global" level, many operations will be blocked needlessly.
From Reduce lock granularity – Concurrency optimization
So, how can we reduce lock granularity? With a short answer, by asking
for locks as less as possible. The basic idea is to use separate locks
to guard multiple independent state variables of a class, instead of
having only one lock in class scope.

First things first: You don't need to implement a LOCK for each of your objects, Delphi's done that for you with the TMonitor class:
TMonitor.Enter(WhateverObject);
try
// Your code goes here.
finally TMonitor.Leave(WhateverObject);
end;
just make sure you free the WhateverObject when your application shuts down, or else you'll run into a bug that I've opened on QC: http://qc.embarcadero.com/wc/qcmain.aspx?d=111795
Secondly, making an application multi-threading is a bit more involved. You can't just wrapp each call between Enter/Leave calls: your "locking" needs to take into account what the object does and what the access pattern is. Wrapping calls within Enter/Leave simply make sure that only one thread runs that method at any time, but race conditions are much more complex, and might arise from successive calls to your locked methods. Even those each method is locked, and only one thread ever called those methods at any given time, the state of the locked object might change between as a consequence of other thread's activity.
This kind of code would be just fine in a single-threaded application, but locking at method level is not enough when switching to multi-threaded:
if List.IndexOf(Something) = -1 then
List.Add(Something);

Related

Setting entry point in DWScript

Is there a way to set an entry point in DWScript?
For example, if I start a script execution, I'd like it to execute a procedure Main, rather than the code in the regular entry point (begin ... end.).
I know it's possible to execute functions from Delphi, but I'm not sure this would be quite the same.
Aside from writing your procedure Main(); and then having your regular script entry point consist of nothing but calling Main, which is probably not what you're thinking of, no, there's no way to do that in DWS.
For all its innovations in syntax, DWS is still Pascal, and it still works the way Pascal works. Asking for some sort of named Main routine would be a radical departure from Pascal style.
EDIT: To answer the clarification posted in comments:
If you want your script to spawn a new script thread, you'll have to handle it in external Delphi code. As of this writing, the DWS system doesn't have any concept of multithreading built in. If you wanted to do it, you'd do something like this:
Create an external routine called something like SpawnThread(EntryPoint: string). Its eval method (out in Native-Delphi-land) would spawn a new thread that loads the current script, then finds the routine with the specified name and executes it.
That's about the only way you could get it to work without language-level support. If you'd like a way to spawn threads from within DWS, try adding it as a feature request to the issue tracker.
Calling functions directly is explicited in
https://code.google.com/p/dwscript/wiki/FirstSteps#Functions
If you want to execute a function in a different thread, you'll need some Delphi-side code to create a new thread, a new execution, and then call your functions. The main and threaded-execution will then be sandboxed from each other (so can't share share global vars etc.).
If you need to share data between the threads, you could do that by exposing functions or external variables, which would call into Delphi code with the proper synchronizations and locks in place (what is "proper" will depend on what your code wants to do, like always in multithreading...).
Note that it is possible to pass objects, interfaces and dynamic arrays between script executions (provided they're executions of the same program), but just like with regular code, you'll have to use locks, critical sections or mutexes explicitly.

How to effectively use interfaces for memory management in Delphi

I'm fairly new to Delphi and have been doing all my memory management manually, but have heard references to Delphi being able to use interfaces to do reference counting and providing some memory management that way. I want to get started with that, but have a few questions.
Just generally, how do I use it. Create the interface and the class implementing it. Then anytime I need that object, have the variable actually be of the Interface type, but instantiate the object and presto? No nee to think about freeing it? No more try-finallys?
It seems very cumbersome to create a bunch of interfaces for classes that really don't need them. Any tips on auto generating those? How do I best organize that? Interface and class in the same file?
What are common pitfalls that might cause me grief? Ex: Does casting the interfaced object to the an object of its class break my reference counting? Or are there any non-obvious ways Delphi would create reference loops? (meaning besides A uses B uses C uses A)
If there are tutorials that cover any of this, that would be great, but I didn't come up with anything in my searches. Thanks.
I am currently working with a very large project that takes advantage of the "side affect" of interface reference counting for the purpose of memory management.
My own personal conclusion is that you end up with a lot of code that is overly complex for no better reason than, "I don't have to worry about calling free"
I would strongly advise against this course of action for some very basic reasons:
1) You are using a side affect that exists for the purpose of COM compatibility.
2) You are making your object footprint and efficiency heavier. Interfaces are pointers to lists of pointers.. or something along those lines.
3) Like you stated... you now have to make piles of interfaces for the sole purpose of avoiding freeing memory yourself... this causes more trouble than it's worth in my opinion.
4) Most common bug that will be a HUGE pain to debug will become when an object gets freed, before it's reference. We have special code in our own reference counting to try and test for this problem before software goes out the door.
Now to answer your questions.
1) Given TFoo and interface IFoo you can have a method like the following
function GetFoo: IFoo;
begin
Result := (TFoo.Create as IFoo);
end;
...and presto, you don't need the finally to free it.
2) Yes like I said, you think it's a great idea, but it turns into a huge pain in the bupkis
3) 2 problems.
A) you have Object1.Interface2 and Object2.Interface1... these objects will never be freed due to the circular reference
B) Freeing the object before all the references are released, I cannot stress how dificult these bugs are to track down...
The most common complaint leading to the desire for "automatic garbage collection" in Delphi is the way that even short-lived temporary objects have to be disposed of manually and that you have to write a fair amount of "boiler-plate" code to ensure that this takes place when exceptions occur.
For example, creating a TStringList for some temporary sorting or other algorithmic purpose within a procedure:
procedure SomeStringsOperation(const aStrings: TStrings);
var
list: TStringList;
begin
list := TStringList.Create;
try
:
// do some work with "list"
:
finally
list.Free;
end;
end;
As you mentioned, objects that implement the COM protocol of reference counted lifetime management avoid this by cleaning themselves up when all references to them have been released.
But since TStringList isn't a COM object, you cannot enjoy the convenience this offers.
Fortunately there is a way to use COM reference counting to take care of these things without have to create all new, COM versions of the classes you wish to use. You don't even need to switch to an entirely COM based model.
I created a very simple utility class to allow me to "wrap" ANY object inside a lightweight COM container specifically for the purpose of getting this automatic cleanup behaiour. Using this technique you can replace the above example with:
procedure SomeStringsOperation(const aStrings: TStrings);
var
list: TStringList;
begin
AutoFree(#list);
list := TStringList.Create;
:
// do some work with "list"
:
end;
The AutoFree() function call creates an "anonymous" interfaced object that is Release()'d in the exit code generated by the compiler for the procedure. This autofree object is passed a pointer to the variable that references the object you wish to be free'd. Among other things this allows us to use the AutoFree() function as a pseudo-"declaration", placing any and ALL AutoFree() calls at the top of the method, as close as possible to the variable declarations that they reference, before we have even created any objects.
Full details of the implementation, including source code and further examples, are on my blog in this post.
The memory management of interfaces is done through implementation of _AddRef and _Release which are implemented by TInterfacedObject.
In general using interfaces to make memory management less cumbersome can be a nice idea, but you need to take care of these things:
Make sure the classes that implement interfaces are derived from TInterfacedObject or roll your own ancestor class that provides good implementations for _AddRef and _Release
Use either/or: so either user interfaces references, or use object instance references, don't mix them. That can be problematic when implementing interfaces in components (as those derive from TComponent, not TInterfacedObject)
Don't go the TInterfacedComponent way as that mixes Owner based memory management and _AddRef/_Release based memory management
Watch circular interface references (you can go around implementing "weak interface references" mentioned here and implemented here)
You need to maintain extra code as you need to define interfaces for the parts your classes that you want to expose, and keep those two in sync (you could Model Maker Code Explorer for this; it allows you to extract interfaces and in general boost your development because it manages the interface/implementation parts of code in single-actions)
You need some extra plumbing to create instances of the underlying classes. You can use the factory pattern for that.
That is not always effectively, but does answer a few of your underlying questions.
Shortest possible answer: The default delphi memory model is that owners free the objects they own. All other references are weak references and must let go before the owner does. "Sharing" an object that has a lifetime shorter than the entire lifetime of the app is rarely done. Reference counting is rarely done, and when it is done, it is only done by experts, or else it adds more bugs and crashes than it solves.
Learn idiomatic delphi style and try to imitate it, don't fight the grain. Sadly, people think that "program against interfaces, not implementations" means "Use IUnknown everywhere". That's not true. I recommend you don't use COM IUnknown interfaces, and use abstract base classes instead. The only thing you can't do is implement two abstract base classes in a single class, and the need for that is rare.
Update: I've recently found it helpful to use COM Interfaces (IUnknown based) to help me separate out my model and controller implementations from my UI classes. So I do find using IUnknown based interfaces useful. But there is not a lot of documentation and prior art out there to base your efforts on. I'd like to see a "cookbook" style recipe that lays all this out for people, so they can work without the usual problem of combining interface and non-interface based lifetime management, and all the trouble that comes while you get used to that extra complexity.
Switching to interfaces only for avoiding manual Free's is senseless. Little economy in Free/try-finally lines will hardly compensate the necessity of declaring both g/setters and properties in the interface not mentioning the necessity of keeping the intf/class declarations in sync. Interfaces also bring performance loss due to implicit finalize code and reference counting. If performance is not the main point and all you want to achieve is autofreeing, I'd recommend using some universal interface wrappers like the one Deltics suggested.

How can I parallelize check spelling using Delphi?

I've got a sort of spell checker written in Delphi. It analyzes the text sentence by sentence.
It encolors wrong items according to some rules after parsing each sentence. The user is able to interrupt this process, which is important.
How can I parallelize this process in general using some 3rd party Delphi libraries?
In the current state I've got on the fly sentence coloration after check. Thus the user sees the progress.
The algorithm would be as such:
Create multiple workers.
Create a spell-checker in each worker.
Grab the text and split it into work units (word or sentences). Each work unit must be accompanied with the location in original text.
Send work units to workers. Good approach is to send data into common queue from which workers are taking work units. Queue must either support multiple readers or you must use locking to access it.
Each worker takes a work unit, runs a spell-check and returns the result (together with the location in the original text) to the owner.
The simplest way to return a result is to send a message to the main thread.
Alternatively, you can write results into a result queue (which must either use locking or support multiple writers) and application can then poll those results (either from a timer or from the OnIdle handler).
How the multiple spell-checkers will access the dictionary is another problem. You can load a copy of the dictionary in each worker or you can protect access to the dictionary with a lock (but that would slow things down). If you are lucky, dictionary is thread-safe for reading and you can do simultaneous queries without locking.
Appropriate OmniThreadLibrary abstraction for the problem would be either a ParallelTask or a BackgroundWorker.
To parallelize, just create a new class descendent from TThread, create an object from it, give part of the job to the new thread, run Execute, and collect the results in the main thread.
Like this:
TMySpellChecker = class(TThread)
protected
FText: String;
FResult: String;
public
procedure Execute; override;
property Text: String read FText write FText;
property Result: String read FResult write FResult;
end;
TMySpellChecker.Execute;
begin
// Analyze the text, and compute the result
end;
In the main thread:
NewThread := TMySpellChecker.Create(True); // Create suspended
NewThread.Text := TextSegment;
NewThread.Execute;
The thread object will then do the analyzing in the background, while the main thread continues to run.
To handle the results, you need to assign a handler to the OnTerminate event of the thread object:
NewThread.OnTerminate := HandleMySpellCheckerTerminate;
This must be done before you run Execute on the thread object.
To allow for interruptions, one possibility is to break the main text up into segments, place the segments in a list in the main thread, and then analyze the segments one by one using the thread object. You can then allow for interruptions between each run.

Stop client code from freeing shared objects in Delphi

I have implemented the FlyWeight pattern in my Delphi application. Everything has worked great, everything is a lot faster and takes less memory, but there is one thing I am worried about.
My implementation will only work as long as client code never calls Free() on the shared objects. In the Flyweight pattern, the FlyweightFactory itself is supposed to "maintain a reference to flyweights" i.e. to the shared objects.
My problem is that there is no (obvious) way to stop other code from destroying the objects once they have a reference. I could live with this, but it would be a "big win" if I could pass these objects round freely without worrying about accidental freeing.
To show a (contrived) example:
flyweight1:=FlyweightFactory.GetFlyweight(42);
WriteLn('Description is '+flyweight.Description);
flyweight1.Free;
flyweight2:=FlyweightFactory.GetFlyweight(42);
WriteLn('Description is '+flyweight.Description);
// Object has already been Freed!; behaviour is undefined
I have considered overriding the destructor as shown here to stop the flyweight object being freed altogether. This is not an option in my case as
a) I only want to stop cached objects from being Freed, not objects that aren't part of the cache. There is a lot of legacy code that doesn't use the cache; they still need to create and free objects manually.
b) I do want the FlyweightFactory to Free the objects during finalization; I agree with Warren P that a "zero leaked memory" policy is best.
I'll leave with a quote from the Flyweight chapter of GoF
Sharability implies some form of
reference counting or garbage
collection to reclaim storage when
it's no longer needed. However,
neither is necessary if the number of
flyweights is fixed and small. In that
case, the flyweights are worth keeping
around permanently.
In my case the flyweights are "fixed" and (sufficiently) small.
[UPDATE See my answer for details of how I solved this problem]
My answer to the question you link to still applies. The objects must know by means of a private boolean flag that they are cached objects. Then they can elect not to destroy themselves in Destroy and FreeInstance. There really is no alternative if you want to allow Free to be called.
To deal with finalization you would want to add the cached objects to a list of cached objects. That list of objects can be freed at finalization time. Of course the flag to disable freeing would have to be reset whilst you walked the list.
Having made this point regarding finalization, I would advise you to register an expected memory leak and just leak this memory. It makes the code much simpler and there's nothing to lose. Any memory you don't free will be reclaimed by the OS as soon as your executable closes. One word of caution: if your code is compiled into a DLL then leaking could be troublesome if your DLL is loaded, unloaded, loaded again etc.
What all this is telling you is that you are swimming against the current. Is it possible that you could achieve your goals with a different solution that fitted better with the way Delphi is steering you?
I suggest to add a reference count in order to known if your shared object is still used.
Every client should use the pattern AddRef / Release (AddRef increases the count; Release decrements it; if count reaches zero Free is called)
The AddRef may be called directly by your GetFlyweight method; Release has to be used instead of Free.
If you refactor your class and extract an interface from it the AddRef/Release pattern in naturally implemented in then interface implementation. (You could derive from TInterfacedObject or implement IInterface by your self)
Ideally you seldom want 2 ways of using the same things. It just complicates matters in the long run. In 6 months time, you might not be sure whether a particular piece of code is using the new flyweight paradigm or the old paradigm.
The best way to prevent someone calling Free or Destroy is to make sure it's not even there. And within the Delphi world, the only way to do that is to use interfaces.
To expand on your contrived example:
type
TFlyweightObject = class
public
constructor Create(ANumber: Integer);
function Description: string;
end;
TFlyweightFactory = class
public
function GetFlyweight(ANumber: Integer): TFlyweightObject;
end;
This being an object can easily be destoyed by a rogue client. You could make the following changes:
type
IFlyweight = interface
//place guid here
function Description: string;
end;
TFlyweightObject = class(TInterfacedObject, IFlyweight)
public
constructor Create(ANumber: Integer);
function Description: string;
end;
TFlyweightFactory = class
public
function GetFlyweight(ANumber: Integer): IFlyweight;
end;
Now any code that is updated to use the flyweight paradigm is forced to use it as intended. It's also easier to recognise the old code that still needs to be refactored because it doesn't use the interface. Old code would still construct the "flyweight" object directly.
You could also hide a destructor by making it protected or private. Programmers won't see it outside the scope of the unit in which it is declared in.
But I am posting this answer more like a curiosity because this will not prevent freeing an object by using FreeAndNil or by using a "Protected Hack"
I managed to get around the problems I cited in my original question using the following techniques, suggested by David Heffernan in his answer.
a) I only want to stop cached objects
from being Freed, not objects that
aren't part of the cache. There is a
lot of legacy code that doesn't use
the cache; they still need to create
and free objects manually.
I fixed this by subclassing the Flyweight class and overriding destroy, BeforeDestruction and FreeInstance in the subclass only. This left the parent class as is. The cache contains instances of the subclass (which can't be freed), whereas objects outside the cache can be freed as per usual.
b) I do want the FlyweightFactory to
Free the objects during finalization;
I agree with Warren P that a "zero
leaked memory" policy is best.
To solve this, I added a private boolean flag that has to be set to true before the object can be freed. This flag can only be set from the Cache Unit, it is not visible to other code. This means that the flag cannot be set outside by code outside the cache.
The destructor just looks like this:
destructor TCachedItem.destroy;
begin
if destroyAllowed then
inherited;
end;
If client code trys to Free a cached object, the call will have no effect.

Confusion of thread synchronization problem

It makes me confused when I read the article by Zarko Gajic today:
"Multithreaded Delphi Database Queries"
Article URL: http://delphi.about.com/od/kbthread/a/query_threading.htm
Sourecode: http://delphi.about.com/library/weekly/code/adothreading.zip
With the code of "TCalcThread.Execute" procedure, Why the following code do not need to be placed in the Synchronize() method to run?
Line 173: ListBox.Clear;
Line 179: ListBox.Items.Insert(......);
Line 188: ListBox.Items.Add('*---------*');
Line 195: TicksLabel.Caption := 'Ticks: ' + IntToStr(ticks);
These codes are operating the VCL components, and are related to the UI updates. In my knowledge, these operations should be use thread synchronize, and executed by the main thread. Is my knowledge has the flaw?
This is a rare case where you're benefiting from the fact that Windows is doing the thread synchronization for you. The reason is that for a listbox, the items are manipulated using SendMessage with control specific messages. Because of this, each SendMessage call makes sure the message is processed by the same thread on which the control was created, notably the main thread.
Like I said, this is a rare case. It is also causing a thread switch for each of those three calls, which will degrade performance. You're still better off using Synchronize to force that block of code to run in the main thread where it belongs. It also ensures that if you begin working with a control that doesn't internally use SendMessage, you won't get bitten.
Indeed. Maybe the sample isn't problematic cause there are no UI changes while the thread is executing. But UI things always have to occur inside the UI thread.
The only differences I see between the sync'ed and the not sync'ed instructions are:
the not sync'ed are not no-params methods so the program will be more dificult to write :)
the sync'ed method is updating a TLabel which is not a TControl (if I remember my Delphi days) so it uses canvas directly...
But anyway: UI is touched by a single thread. Always. Once I wanted to update a TTreeBox inside a thread (no paralelism nor cross updates, simply a separate thread) and it was a very bad thing (random errors)...

Resources