Hi Joel,

> On Nov 16, 2025, at 05:53, Joel Jacobson <[email protected]> wrote:
> 
> The attached v28 is the same as v27, except some comments have been
> fixed to accurately reflect the code.
> 
> /Joel<0001-optimize_listen_notify-v28.patch><0002-optimize_listen_notify-v28.patch>

Thanks for the continuous effort on this patch. Finally, I got some time, after 
revisiting v28 throughoutly, I think it’s much better now. Just got 2 more 
comments:

1
```
+       if (asyncQueueControl->channelHashDSH == DSHASH_HANDLE_INVALID)
+       {
+               /* Initialize dynamic shared hash table for channel hash */
+               channelDSA = dsa_create(LWTRANCHE_NOTIFY_CHANNEL_HASH);
+               dsa_pin(channelDSA);
+               dsa_pin_mapping(channelDSA);
+               channelHash = dshash_create(channelDSA, &channelDSHParams, 
NULL);
+
+               /* Store handles in shared memory for other backends to use */
+               asyncQueueControl->channelHashDSA = dsa_get_handle(channelDSA);
+               asyncQueueControl->channelHashDSH =
+                       dshash_get_hash_table_handle(channelHash);
+       }
+       else if (!channelHash)
+       {
+               /* Attach to existing dynamic shared hash table */
+               channelDSA = dsa_attach(asyncQueueControl->channelHashDSA);
+               dsa_pin_mapping(channelDSA);
+               channelHash = dshash_attach(channelDSA, &channelDSHParams,
+                                                                       
asyncQueueControl->channelHashDSH,
+                                                                       NULL);
+       }
```

DSA is created and pinned by the first backend and every backend 
isa_in_mapping, but I don’t see any unpin, is it a problem? If unpin is not 
needed, why are they provided?

2
```
+                       entry = dshash_find(channelHash, &key, false);
+               }
+
+               if (entry == NULL)
+                       continue;                       /* No listeners 
registered for this channel */
+
+               listeners = (ProcNumber *) dsa_get_address(channelDSA,
+                                                                               
                   entry->listenersArray);
+
+               for (int j = 0; j < entry->numListeners; j++)
+               {
+                       ProcNumber      i = listeners[j];
+                       int32           pid;
+                       QueuePosition pos;
+
+                       if (QUEUE_BACKEND_WAKEUP_PENDING(i))
+                               continue;
+
+                       pos = QUEUE_BACKEND_POS(i);
+                       pid = QUEUE_BACKEND_PID(i);
+
+                       /* Skip if caught up */
                        if (QUEUE_POS_EQUAL(pos, QUEUE_HEAD))
                                continue;
+
+                       Assert(pid != InvalidPid);
+
+                       QUEUE_BACKEND_WAKEUP_PENDING(i) = true;
+                       pids[count] = pid;
+                       procnos[count] = i;
+                       count++;
                }
-               else
+
+               dshash_release_lock(channelHash, entry);
```

SignalBackends() now holds the dshash entry lock for long time, while other 
backend’s LISTEN/UNLISTEN all needs to acquire the lock. So, my suggestion is 
to copy the listeners array to local then quickly release the lock.


Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Reply via email to