bvarga / delphizmq

0MQ Delphi binding
GNU Lesser General Public License v3.0
137 stars 63 forks source link

Question on Critical Sections and Private CTRTLCriticalSection in TZMQPoller thread class #30

Open tempusscott opened 2 years ago

tempusscott commented 2 years ago

Inside zmpapi.pas, we have two different critical section lock records.

Both are named: cs: TRTLCriticalSection

One is global to the implementation section of this unit, and one is a private variable inside the TZMQPoller thread. And they share the same name, but I don't see what the cs inside TZMQPoller does. It would be ambiguous and the private cs appears to do nothing.

Can the TZMQPoller thread use and share the cs that is global to this unit instead? Thank you for any feedback.

bvarga commented 2 years ago

The one inside TZMQPoller protects the poller methods so those can be called from different threads, the global one is protecting socket creation and deletion.

tempusscott commented 2 years ago

I probably do not understand enough how critical sections work. I thought that to control access, they had to be shared in some way to actually block access. When I read the code, I see that each instance of TZMQPoller gets its own critical section variable.

So in the current implementation if there were three poller threads: Poller 1 has a cs CritSection variable. Poller 2 has its own cs variable. Poller 3 has its own cs variable.

If P1 uses its cs critical section, no other thread will know, or be blocked or have any way of noticing. It is all internal to P1. If P2 uses its cs critical section, no other thread will know, or be blocked or have any way of noticing. It is all internal to P2. If P3 uses its cs critical section, no other thread will know, or be blocked or have any way of noticing. It is all internal to P3.

A critical section acts as a gate, but I thought it only acted as a gate if two or more threads were attempting to use one shared gate and one thread locked and unlocked it and then the other thread could do the same.

Thank you very much for your time. If I am misunderstanding how critical section variables work, I would very much like to know!

bvarga commented 2 years ago

Yes you are right, I think the same about critical sections.

Each critical section in the TZMQPoller class protects its private fPollItem, and fPollSocket arrays, they are not shared between instances, this way you can call AddToPollItems and the other methods from different threads for an instance (P1).

If there's another instance (P2) it's safe to call the same methods in the same time with P1, since it has a different fPollItem and fPollSockets arrays, those are not shared.

The global CriticalSection is for protecting the zmq_socket calls, which are shared, all of the instances calls the same zmq_socket functions.