Sorry to bother you, now I know that there is no problem here.

The model for reading and writing of PGXACT::xid and 
ShmemVariableCache->latestCompletedXid can be simplified as follows:

     backend A                         backend B                               
backend C
  wlock(XidGenLock);           wlock(XidGenLock);               
rlock(ProcArrayLock);
  write APgXact->xid;         write BPgXact->xid;               read 
latestCompletedXid;
  unlock(XidGenLock);         unlock(XidGenLock);              read 
APgXact->xid;
                                          ...                                   
        read BPgXact->xid;
                                          wlock(ProcArrayLock);            
unlock(ProcArrayLock);
                                          write latestCompletedXid;
                                          unlock(ProcArrayLock);

My previous problem was that C might not be able to see the value of 
APgXact->xid written by A because there was no obvious acquire-release 
operation during this. But now I find that there are already some 
acquire-release operations here. Because of the `unlock(XidGenLock)` in A and 
`wlock(XidGenLock)` in B and the rules introduced in [Inter-thread 
happens-before](https://en.cppreference.com/w/cpp/atomic/memory_order), we can 
know that the `write APgXact->xid` in A inter-thread happens before `write 
BPgXact->xid` in B. And `write BPgXact->xid` is sequenced before `write 
latestCompletedXid` in B according to rules introduced in [Sequenced-before 
rules](https://en.cppreference.com/w/cpp/language/eval_order). And similarly 
`write latestCompletedXid` in B inter-thread happens before `read 
latestCompletedXid` in C. So the `write APgXact->xid` in A inter-thread happens 
before `read APgXact->xid` in C. So C can see the value of APgXact->xid written 
by A.

Reply via email to