[DUG] Program crashes - anyone knows why?

Matthew Comb matt at ferndigital.com
Mon Nov 27 12:41:06 NZDT 2006


Yes this looks problematic.

Your critical section needs to be attached to something e.g. be global or
belonging to an object.

There are a number of ways you could fix this, probably the easiest way in
this case is to move your AddItem method to your mainform and make sure
that your form creates and destroys a critical section or similar that is
used (but not discarded) in your addItem routine. To be clear do not
create critical sections as local variables. They are intended to be
shared between threads.

Note that its better to seperate all of this into a container object
rather than put it into your mainform, but at least you will know whether
this is your problem.

Hope this helps.

Matt.

> On Mon, 27 Nov 2006 00:14:39 +0100, Matthew Comb <matt at ferndigital.com>
> wrote:
>
>> You are creating your critical section within your worker thread. This
>> won't protect anything as all of your worker threads will have their own
>> instance of the critical section.
>
> Hmm, I do this at a few more places too. What should I do instead?
> Actually, THIS may be what's causing the error. When I process a keyword,
> I put the result into the following structure:
>
>    GoogleResult = ^ResultRec;
>    ResultRec = packed record
>      next: GoogleResult;
>      srNo: integer;
>      // etc...
>    end;
>
> This GoogleResult is then used as a global variable. The main form has a
> public property
> ResultList: GoogleResult. Each thread has a pointer back to the main form.
> To ass the result to the list, I write
>
> AddItem(mainForm.ResultList, newItem);
>
> And this is the procedure:
>
> procedure AddItem(var list: GoogleResult; const item: GoogleResult);
> var
>    tmp: GoogleResult;
>    critical: _RTL_CRITICAL_SECTION;
> begin
>    try
>      InitializeCriticalSection(critical);
>      EnterCriticalSection(critical);
>      if list = nil then
>        list := item
>      else begin
>        tmp := list;
>        while tmp^.next <> nil do
>          tmp := tmp^.next;
>        tmp^.next := item;
>      end;
>      LeaveCriticalSection(critical);
>      DeleteCriticalSection(critical);
>    except on Exception do { nothing }
>    end
> end;
>
> You see I've put everything in a critical section? So this won't do
> anything because I'm calling the procedure from the thread? What should I
> do instead, use Synchronize?
> Hmm or maybe I should just use a TThreadList here as well. I've left this
> old list for historical reasons (in the previous version the program was
> single threaded).
>
>> You are creating your critical section to access a boolean ? This is not
>> needed as you cannot have a conflict on a boolean type.
>
> There's a checkbox on the main form which enables/disables caching. If I
> change it while a thread is accessing the variable then there can be a
> conflict.
>
>> Are any of your worker threads passed the same file name ? This for sure
>> would cause a problem.
>
> No they each create their own random-named file, before making sure it
> doesn't exist.
>
> Csaba
>
> _______________________________________________
> Delphi mailing list
> Delphi at ns3.123.co.nz
> http://ns3.123.co.nz/mailman/listinfo/delphi
>




More information about the Delphi mailing list