Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Are both TIdUDPServer's SendBuffer and Broadcast reentrant/thread safe?



Permlink Replies: 4 - Last Post: Jan 15, 2017 12:31 AM Last Post By: Arkady Semylio Threads: [ Previous | Next ]
Arkady Semylio

Posts: 87
Registered: 9/18/15
Are both TIdUDPServer's SendBuffer and Broadcast reentrant/thread safe?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 13, 2017 2:22 AM
I'm using a single TIdUDPServer component in a service application. With this component,
the data are sent to some IoT devices, using both TIdUDPServer::SendBuffer() and
TIdUDPServer::Broadcast() methods from multiple threads. These IoT devices respond
to TIdUDPServer wich processes the received datagrams in a method handler assigned
to the OnUDPRead event, then dispatch the replyed data to the proper data structures.

So the questions is: are both the TIdUDPServer::SendBuffer() and TIdUDPServer::Broadcast()
reentrant/thread safe, as I have a single TIdUDPServer component? If it's possible,
I don't want neither to put a mutex to protect the multiple access to the TIdUDPServer::SendBuffer()
and TIdUDPServer::Broadcast() methods of the unique TIdUDPServer component
or to use multiple separated TIdUDPClient components to send data, above all if
TIdUDPServer::SendBuffer() and TIdUDPServer::Broadcast() methods are already
thread safe/reentrant.

TIA

Bye bye
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Are both TIdUDPServer's SendBuffer and Broadcast reentrant/thread safe?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 13, 2017 3:12 PM   in response to: Arkady Semylio in response to: Arkady Semylio
Arkady wrote:

So the questions is: are both the TIdUDPServer::SendBuffer() and
TIdUDPServer::Broadcast() reentrant/thread safe, as I have a single
TIdUDPServer component?

TIdUDPServer.SendBuffer() is typically thread-safe - provided TIdUDPServer.Active
is set to True beforehand (otherwise multiple threads may try to implicitly
re-allocate the same Binding socket at the same time, causing conflicts),
and TIdUDPServer is not deactivated while sending.

TIdUDPServer.Broadcast() is a little less thread-safe then SendBuffer(),
because it invokes additional method calls to manipulate the socket's SO_BROADCAST
flag before/after sending each broadcast packet. If the Binding object's
BroadcastEnabled property is set to True beforehand, those extra method calls
should have no/minimal impact since the flag will just be enabled over and
over when it is already enabled, so you would not really be changing anything.

If possible for your design, I would suggest using two separate sockets,
one for sending and one for broadcasting. You can either:

1. use two separate TIdUDPServer objects, where one has BroadcastEnabled
set to true. Then you can have your threads use the appropriate TIdUDPServer,
calling SendBuffer() and Broadcast() normally as needed.

2. use a single TIdUDPServer object with two entries in its Bindings collection,
where one of them has BroadcastEnabled set to true. Then have your threads
access the appropriate Binding when needed, calling TIdSocketHandle.SendTo()
directly (prefferably not TIdSocketHandle.Broadcast(), to avoid the extra
method calls). Don't use the methods of TIdUDPServer itself, as they always
use the first Binding in the Bindings collection.

If you use a single socket, the SO_BROADCAST flag is required in order to
send to a broadcast address. You could set BroadcastEnabled to True beforehand,
and then use SendBuffer() only for both broadcast and non-broadcast packets,
using an appropriate address for each. SendBuffer() and Broadcast() send
data the same way, Broadcast() simply enables SO_BROADCAST before sending
and then resets it afterwards.

Otherwise, if you want to use SendBuffer() and Broadcast() on a single socket,
you should serialize access to it.

If it's possible, I don't want neither to put a mutex to protect the multiple
access to the TIdUDPServer::SendBuffer() and TIdUDPServer::Broadcast()
methods of the unique TIdUDPServer component or to use multiple separated
TIdUDPClient components to send data

Why?

--
Remy Lebeau (TeamB)
Arkady Semylio

Posts: 87
Registered: 9/18/15
Re: Are both TIdUDPServer's SendBuffer and Broadcast reentrant/thread safe?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 14, 2017 12:13 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Ok. Thanks for the infos.

Remy Lebeau (TeamB) wrote:
Arkady wrote:

is set to True beforehand (otherwise multiple threads may try to implicitly

Yes, it's set to true when the service's main thread starts.

If it's possible, I don't want neither to put a mutex to protect the multiple
access to the TIdUDPServer::SendBuffer() and TIdUDPServer::Broadcast()
methods of the unique TIdUDPServer component or to use multiple separated
TIdUDPClient components to send data

Why?

Ok, so I have to semaphorize the calls? Normally I woldn't put a semaphore
to protect a call to a function that's reentrant (that uses only local vars and
don't uses shares system resource that aren't thread safe).

So do you think I have to put a mutex/critsect ?

Thank you

Bya
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Are both TIdUDPServer's SendBuffer and Broadcast reentrant/threadsafe?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 14, 2017 12:00 PM   in response to: Arkady Semylio in response to: Arkady Semylio
Arkady wrote:

Ok, so I have to semaphorize the calls?

If you use both SendBuffer() and Broadcast() on the same Binding socket,
yes.

If you use only SendBuffer(), where BroadcastEnabled has been enabled beforehand,
then no.

Normally I woldn't put a semaphore to protect a call to a
function that's reentrant (that uses only local vars and
don't uses shares system resource that aren't thread safe).

Broadcast() is not reentrant/thread-safe. SendBuffer() is.

--
Remy Lebeau (TeamB)
Arkady Semylio

Posts: 87
Registered: 9/18/15
Re: Are both TIdUDPServer's SendBuffer and Broadcast reentrant/threadsafe?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2017 12:31 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Arkady wrote:

Ok, so I have to semaphorize the calls?

If you use both SendBuffer() and Broadcast() on the same Binding socket,
yes.

Ok. Many thanks for the clarifications.

Bye
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02