I'm having a bit of trouble with a complex program that I've been writing for some time.
There is a gui thread, and a control thread which sends commands to and receives responses from an external device.
There are therefore packets that get sent to the device, and packets that are waited for (with timeouts) and processed.
As I'm not a fantastic programmer I tend to use simple variables, strings, records etc for most stuff, but as there packets are begin passed between so many different units for different layers of the various protocol stacks I thought that this would be one area where it would be a really good idea to create a record and just pass pointers to the record around so that as it gets processed the actual packet doesn't constantly get moved around.
So, when a user clicks on something that starts the process it's easy enough because the main control unit can "new(myrecord)" and then that can be used for the current send/receive packet etc. and then kick off the right bit of code to do the thing that the user requests.
The problem come when the user wishes the process to stop.
The control unit can set a variable "running" in the packet handling unit (these are in the same thread) and this so stuff in the packet handling unit works
got_packet:=false;
repeat
check_for_a_packet(fpmyrecord)); //gets a packet, puts it in the record, sets got_packet
timeout:=check_the_clock(maxtime);
poll_control(10);
until got_packet OR timeout OR (NOT running);
if got_packet then process_packet(fpmyrecord);
the poll_control(10) is a critical part of the code.
it behaves like sleep(10) but instead of doing nothing it runs a bunch of central loops that run some
every1ms
every10ms
every100ms
procedures
every single loop in the entire project uses poll_control(number) so that the control unit can check for user input and maintain stuff that it needs to etc
Now this is my problem;
in the main control unit I have a procedure that runs if the user clicked stop, or the program wants to close or something
procedure TControl.start;
begin
new(myrecord);
PacketCode.Create;
PacketCode.pmyrecord:=myrecord; //sets fpmyrecord in the packetcode
PacketCode.Start;
PacketCode.Running:=true;
end;
procedure TControl.stop;
begin
PacketCode.Running:=false; //property that tells PacketCode to quit any repeat until loops
PacketCode.Terminate;
dispose(myrecord);
end;
The problem is that I guess that if my repeat until loop accessed fpmyrecord after the "dispose" has run but before the "until (NOT running)" then I get a seg fault or something.
I suppose that I could create a readable property such as PacketCode.Finished and set it and the end of every loop with a
if NOT running then fFinished:=true;
then do
repeat
sleep(1);
until PacketCode.Finished;
before the dispose
but I'm just wondering if my whole idea is wrong and if there is a standard and better way to do this kind of thing
any comments gladly received.