Recent

Author Topic: TThread in TList. Acces to TTCPBlockSocket methods  (Read 3851 times)

and_rivne

  • Newbie
  • Posts: 6
TThread in TList. Acces to TTCPBlockSocket methods
« on: August 09, 2018, 02:46:40 pm »
Hi All!
Initial data:

Code: Pascal  [Select][+][-]
  1. uses  blcksock; //from synapse
  2.  
  3. type
  4.    TClientThread = class(TThread)
  5.    public
  6.      Socket: TTCPBlockSocket;
  7.    end;
  8.  
  9. var
  10.   Socket: TTCPBlockSocket;
  11.   T: TClientThread;
  12.   ThreadList: TList;
  13.  
  14.  

I launch a thread in which I wait for connection from web browsers. Add pointer thread in TList

Code: Pascal  [Select][+][-]
  1. Socket.CreateSocket;
  2. Socket.Bind(Socket.LocalName,'57777');
  3.  
  4. repeat
  5.   if Socket.CanRead(100) then
  6.        begin
  7.           T:=TClientThread.Create(Socket.Accept);
  8.           ThreadList.Add(pointer(T));                  
  9.           T.Start;
  10.        end;
  11. until Terminated;

After several requests from the browser, I rewind the elements and I want to call SendString for the socket.

Code: Pascal  [Select][+][-]
  1. var
  2.   cln : TClientThread;
  3.  
  4. for i:=0 to ThreadList.Count-1 do
  5.   begin
  6.     cln := TClientThread(ListenerClient.ThreadList.Items[i]).Socket.SendString('ok');
  7.   end;


But the data is sent only for the element with index 0. For others I get the error SIGSEGV
Have I correctly stored the sockets from the client in TList?

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: TThread in TList. Acces to TTCPBlockSocket methods
« Reply #1 on: August 09, 2018, 03:13:56 pm »
Tlist is not threadsafe, although with care you can use it as you did. Use TThreadList from classes or TThreadlist<T> from rtl-generics (generics.collections.pas)
The latter can greatly simplify your code as well. TThreadlist<TClientThread>; !! No  more casts...

Also note specifically the last part of your code looks fishy to me: you are doing the sendstring from the context of the main thread, not from the threads.
I suspect you need a redesign.
« Last Edit: August 09, 2018, 03:36:33 pm by Thaddy »
Specialize a type, not a var.

and_rivne

  • Newbie
  • Posts: 6
Re: TThread in TList. Acces to TTCPBlockSocket methods
« Reply #2 on: August 09, 2018, 07:59:41 pm »
Thanks for the answer.
Yes, I'm trying to send data from another class, to a higher level.
I do not understand why:
Code: Pascal  [Select][+][-]
  1. cln := TClientThread(ListenerClient.ThreadList.Items[0]).Socket.SendString('ok');
//Items[0]  working
but
Code: Pascal  [Select][+][-]
  1. cln := TClientThread(ListenerClient.ThreadList.Items[1]).Socket.SendString('ok');
// Items[1] does not work.
And the data reaches the client (a few times), but there is an exception.

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: TThread in TList. Acces to TTCPBlockSocket methods
« Reply #3 on: August 10, 2018, 12:10:58 am »
Yes, I'm trying to send data from another class, to a higher level.

Although threads are classes (objects) and can have their own data and methods, they are not intended to be containers.
A typical usage of threads is like a rocket: you setup it, you launch it and wait (or not) until they finish. They should do a job autonomously. Of course, a two-way communication is possible (with known limitations), but definitely you should not touch (directly) thread's internal data in the middle of the work.
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

and_rivne

  • Newbie
  • Posts: 6
Re: TThread in TList. Acces to TTCPBlockSocket methods
« Reply #4 on: August 10, 2018, 09:11:53 am »
What are the options to save threads, except for the TList ?
I did not understand how to get an element from a TThreadlist, and do not delete it.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: TThread in TList. Acces to TTCPBlockSocket methods
« Reply #5 on: August 10, 2018, 10:18:37 am »
just a quick note.
1) the code you posted makes no sense what so ever.
2) the code you posted is too short to analyze the execution flow.
3) if the tlist that holds a list of threads is to be accessed from multiple threads then it is better to use a TThreadedList instead. At list that will give you some protection against list corruption.

other than that I need to see the execution method of TClientThread as well as the complete procedure of the loop you just posted before I can decide if the code you posted has any relevance to the problem you are having let alone pin point the problem it self.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

and_rivne

  • Newbie
  • Posts: 6
Re: TThread in TList. Acces to TTCPBlockSocket methods
« Reply #6 on: August 10, 2018, 12:18:26 pm »
Quote
other than that I need to see the execution method of TClientThread
Code: Pascal  [Select][+][-]
  1. while not Terminated  do
  2.    begin
  3.     if Socket.WaitingData > 0 then
  4.      begin
  5.       s:=Socket.RecvPacket(2000);
  6.       if Socket.LastError = 0 then
  7.         begin
  8.           ProcessingData(S);// we process the data before sending it to the server
  9.         end;
  10.       end;
  11.     sleep(10);
  12.    end;  

The stream expects data from the user and passes on to server.
The problem is that I can not send the result from server to user
Code: Pascal  [Select][+][-]
  1. cln := TClientThread(ListenerClient.ThreadList.Items[1]).Socket.SendString('ok');

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: TThread in TList. Acces to TTCPBlockSocket methods
« Reply #7 on: August 10, 2018, 01:31:02 pm »
I'm very confused by your usage of terms client, server, thread, stream.
It seems like your TClientThread is actually a Peer Thread on a server.

In thast case you should call (a response from server to client (browser) )
  Socket.SendString('ok');
after or inside
  ProcessingData(S);
as a part of your logical protocol.


Anyway, it seems like you're trying to implement a usual webserver (with Synapse).
There are Synapse server demo, FPC's TFPHttpServer.
Why don't you use it?




 
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

and_rivne

  • Newbie
  • Posts: 6
Re: TThread in TList. Acces to TTCPBlockSocket methods
« Reply #8 on: August 10, 2018, 02:13:41 pm »
Yes you are right. This part of the code is similar to the operation of a web server.
After the first request, the browser returns to the page. And this code is executed:
Code: Pascal  [Select][+][-]
  1. cln := TClientThread(ListenerClient.ThreadList.Items[0]).Socket.SendString('.... http body page....');
index=0
Then the browser sends requests for css and images in multiple threads simultaneously, which I save for return the result but here we get the error:
Code: Pascal  [Select][+][-]
  1. cln := TClientThread(ListenerClient.ThreadList.Items[1]).Socket.SendString('...css file code ...');
index=1
sash, thank you for understanding the logic. You most accurately understand the situation.

The task: to intercept requests from the browser, process them and return result.
« Last Edit: August 10, 2018, 02:19:00 pm by and_rivne »

 

TinyPortal © 2005-2018