First thread use for OpenNetworkConnection, any expert tips?

Just starting out? Need help? Post your questions and find answers here.
hoerbie
Enthusiast
Enthusiast
Posts: 119
Joined: Fri Dec 06, 2013 11:57 am
Location: DE/BY/MUC

First thread use for OpenNetworkConnection, any expert tips?

Post by hoerbie »

Hi,

I'm actually making my first small steps with threads in PB, only for opening new network connections. I found a lot of helpful postings in the board and hopefully learned a lot, but just want to be sure to make everything right. So I hope, that the thread experts have a look on my shortened code and tell me of errors.

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_Thread = 0
  CompilerError "compile as thread safe is needed!"
CompilerEndIf

Structure mythreadstruct
  device.u
  connid.i
  name.s
  port.l
  timeout.l
EndStructure
Structure mydevices
  name.s
  connected.u
  connid.i
  *mystart.mythreadstruct
EndStructure
Global Dim devices.mydevices(10)
Enumeration #PB_Event_FirstCustomValue
  #ConnectThread
EndEnumeration

Procedure startup()
  Protected dev.u
  For dev = 1 To 10
    devices(dev)\mystart = AllocateStructure(mythreadstruct)
    devices(dev)\mystart\device = dev
    devices(dev)\mystart\name = "192.168.178."+Str(100+dev)
    devices(dev)\mystart\port = 5577  ;20007
    devices(dev)\mystart\timeout = 10000
  Next dev
EndProcedure

Procedure connect_thread(*start.mythreadstruct)
  Protected ret.i
  ret = OpenNetworkConnection(*start\name,*start\port,#PB_Network_TCP | #PB_Network_IPv4,*start\timeout)
  *start\connid = ret
  PostEvent(#ConnectThread,1,*start\device)
EndProcedure  

Procedure event_thread(dev.u)
  If devices(dev)\mystart\connid <> 0
    devices(dev)\connid = devices(dev)\mystart\connid
    Debug "Connected "+Str(dev)
    devices(dev)\connected = 2
  Else
    devices(dev)\connid = 0
    Debug "Not Connected "+Str(dev)
    devices(dev)\connected = 0
  EndIf
EndProcedure

Procedure job_queue(dev.u)
  ;......
EndProcedure

Procedure main()
  Protected dev.u,sysend.u,event.i
  ;.....
  startup()
  OpenWindow(1,10,10,200,100,"Thread Testing",#PB_Window_TitleBar | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
  InitNetwork()
  Repeat
    event = WaitWindowEvent(50)
    If event
      Select event
        Case #PB_Event_CloseWindow
          sysend = 1
        Case #ConnectThread
          event_thread(EventGadget())
      EndSelect 
    Else
      For dev = 1 To 10
        If devices(dev)\connected = 0
          Debug "Start Connect "+Str(dev)
          devices(dev)\connected = 1
          CreateThread(@connect_thread(),devices(dev)\mystart)
        ElseIf devices(dev)\connected = 2
          job_queue(dev)
        EndIf
      Next dev
    EndIf
  Until sysend
  CloseWindow(1)
EndProcedure

main()
Questions:
-Am i right, that I don't need any mutex or semaphore, because I simply give a pointer to a structure to the thread, and this structure is only accessed from thread and after my event of ended thread?
-Is OpenNetworkConnection thread safe to be used multiple at the same time or should this be only used one after one? My program seems to work, network receive and send is not done in a thread.
-Would it be better, to have every thread open forever and only send a "start reconnect" to a waiting thread, or is it safe or/and better to use short living threads only for one reconnect and let them die after? Thinking of memory leaks etc....
-Using "protected" vars in the thread procedure is enough, or must this vars be "threaded"?

Explanation:
This program in full version is used to control some devices, that are connected to the computer through RS232 or network. The devices normally are getting connected on program startup and then the connection is hold open with status requests every minute or by doing real actions on the devices.
On serial-cabled and network-cabled devices there is no problem in opening and holding the connection, but on Wifi the devices don't switch fast enough between multiple access points, so the connection gets lost sometimes and needs to get reconnected.
For the real actions with the connected devices until now I don't needed threads, the sent and received data is not so time critical, that it can't be solved in one working queue, one device after the other, as there are <= 10 devices.
But the problem is the reconnect on Wifi, sometimes it is fast, but sometimes it needs 5-10 seconds to find a device on an new access point, or sometimes a device simply is offline and the timeout of OpenNetworkConnection is reached. This timeout of 10 seconds is too critical for handling from the queue of the other connected devices, and really short timeouts of 250ms to often don't reach the devices...

In case anyone is interested: program is used to manage payment on credit/debit card terminals via zvt.

Greetings, Hoerbie