Index: src/backend/commands/user.c =================================================================== RCS file: /home/alvherre/cvs/pgsql-server/src/backend/commands/user.c,v retrieving revision 1.141 diff -c -r1.141 user.c *** src/backend/commands/user.c 26 May 2004 04:41:12 -0000 1.141 --- src/backend/commands/user.c 27 Jun 2004 21:49:37 -0000 *************** *** 44,51 **** extern bool Password_encryption; ! static bool user_file_update_needed = false; ! static bool group_file_update_needed = false; static void CheckPgUserAclNotNull(void); --- 44,63 ---- extern bool Password_encryption; ! /* ! * The need-to-update-files flags are a pair of TransactionId that show what ! * level of the transaction tree requested the update. To register an update, ! * the transaction saves its own TransactionId in the flag, unless the value ! * was already set to a valid TransactionId. If it aborts and the value is its ! * TransactionId, it resets the value to InvalidTransactionId. If it commits, ! * it changes the value to its parent's TransactionId. This way the value is ! * propagated up to the topmost transaction, which will update the files if a ! * valid TransactionId is detected. ! * ! * This is the same logic used for RelcacheInitFileInval in inval.c. ! */ ! static TransactionId user_file_update_needed = InvalidTransactionId; ! static TransactionId group_file_update_needed = InvalidTransactionId; static void CheckPgUserAclNotNull(void); *************** *** 402,409 **** Datum update_pg_pwd_and_pg_group(PG_FUNCTION_ARGS) { ! user_file_update_needed = true; ! group_file_update_needed = true; return PointerGetDatum(NULL); } --- 414,424 ---- Datum update_pg_pwd_and_pg_group(PG_FUNCTION_ARGS) { ! if (user_file_update_needed == InvalidTransactionId) ! user_file_update_needed = GetCurrentTransactionId(); ! ! if (group_file_update_needed == InvalidTransactionId) ! group_file_update_needed = GetCurrentTransactionId(); return PointerGetDatum(NULL); } *************** *** 429,441 **** Relation urel = NULL; Relation grel = NULL; ! if (!(user_file_update_needed || group_file_update_needed)) return; if (!isCommit) { ! user_file_update_needed = false; ! group_file_update_needed = false; return; } --- 444,457 ---- Relation urel = NULL; Relation grel = NULL; ! if (user_file_update_needed == InvalidTransactionId && ! group_file_update_needed == InvalidTransactionId) return; if (!isCommit) { ! user_file_update_needed = InvalidTransactionId; ! group_file_update_needed = InvalidTransactionId; return; } *************** *** 447,468 **** * pg_shadow or pg_group, which likely won't have gotten a strong * enough lock), so get the locks we need before writing anything. */ ! if (user_file_update_needed) urel = heap_openr(ShadowRelationName, ExclusiveLock); ! if (group_file_update_needed) grel = heap_openr(GroupRelationName, ExclusiveLock); /* Okay to write the files */ ! if (user_file_update_needed) { ! user_file_update_needed = false; write_user_file(urel); heap_close(urel, NoLock); } ! if (group_file_update_needed) { ! group_file_update_needed = false; write_group_file(grel); heap_close(grel, NoLock); } --- 463,484 ---- * pg_shadow or pg_group, which likely won't have gotten a strong * enough lock), so get the locks we need before writing anything. */ ! if (user_file_update_needed != InvalidTransactionId) urel = heap_openr(ShadowRelationName, ExclusiveLock); ! if (group_file_update_needed != InvalidTransactionId) grel = heap_openr(GroupRelationName, ExclusiveLock); /* Okay to write the files */ ! if (user_file_update_needed != InvalidTransactionId) { ! user_file_update_needed = InvalidTransactionId; write_user_file(urel); heap_close(urel, NoLock); } ! if (group_file_update_needed != InvalidTransactionId) { ! group_file_update_needed = InvalidTransactionId; write_group_file(grel); heap_close(grel, NoLock); } *************** *** 473,479 **** --- 489,522 ---- SendPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE); } + /* + * AtEOSubXact_UpdatePasswordFile + * + * Called at subtransaction end, this routine resets or updates the + * need-to-update-files flags. + */ + void + AtEOSubXact_UpdatePasswordFile(bool isCommit) + { + TransactionId myXid = GetCurrentTransactionId(); + if (isCommit) + { + if (user_file_update_needed == myXid) + user_file_update_needed = GetParentTransactionId(); + + if (group_file_update_needed == myXid) + group_file_update_needed = GetParentTransactionId(); + } + else + { + if (user_file_update_needed == myXid) + user_file_update_needed = InvalidTransactionId; + + if (group_file_update_needed == myXid) + group_file_update_needed = InvalidTransactionId; + } + } /* * CREATE USER *************** *** 728,734 **** /* * Set flag to update flat password file at commit. */ ! user_file_update_needed = true; } --- 771,778 ---- /* * Set flag to update flat password file at commit. */ ! if (user_file_update_needed == InvalidTransactionId) ! user_file_update_needed = GetCurrentTransactionId(); } *************** *** 925,931 **** /* * Set flag to update flat password file at commit. */ ! user_file_update_needed = true; } --- 969,976 ---- /* * Set flag to update flat password file at commit. */ ! if (user_file_update_needed == InvalidTransactionId) ! user_file_update_needed = GetCurrentTransactionId(); } *************** *** 1147,1153 **** /* * Set flag to update flat password file at commit. */ ! user_file_update_needed = true; } --- 1192,1199 ---- /* * Set flag to update flat password file at commit. */ ! if (user_file_update_needed == InvalidTransactionId) ! user_file_update_needed = GetCurrentTransactionId(); } *************** *** 1233,1239 **** ReleaseSysCache(oldtuple); heap_close(rel, NoLock); ! user_file_update_needed = true; } --- 1279,1286 ---- ReleaseSysCache(oldtuple); heap_close(rel, NoLock); ! if (user_file_update_needed == InvalidTransactionId) ! user_file_update_needed = GetCurrentTransactionId(); } *************** *** 1438,1444 **** /* * Set flag to update flat group file at commit. */ ! group_file_update_needed = true; } --- 1485,1492 ---- /* * Set flag to update flat group file at commit. */ ! if (group_file_update_needed == InvalidTransactionId) ! group_file_update_needed = GetCurrentTransactionId(); } *************** *** 1590,1596 **** /* * Set flag to update flat group file at commit. */ ! group_file_update_needed = true; } /* --- 1638,1645 ---- /* * Set flag to update flat group file at commit. */ ! if (group_file_update_needed == InvalidTransactionId) ! group_file_update_needed = GetCurrentTransactionId(); } /* *************** *** 1730,1736 **** /* * Set flag to update flat group file at commit. */ ! group_file_update_needed = true; } --- 1779,1786 ---- /* * Set flag to update flat group file at commit. */ ! if (group_file_update_needed == InvalidTransactionId) ! group_file_update_needed = GetCurrentTransactionId(); } *************** *** 1776,1780 **** heap_close(rel, NoLock); heap_freetuple(tup); ! group_file_update_needed = true; } --- 1826,1831 ---- heap_close(rel, NoLock); heap_freetuple(tup); ! if (group_file_update_needed == InvalidTransactionId) ! group_file_update_needed = GetCurrentTransactionId(); } Index: src/include/commands/user.h =================================================================== RCS file: /home/alvherre/cvs/pgsql-server/src/include/commands/user.h,v retrieving revision 1.22 diff -c -r1.22 user.h *** src/include/commands/user.h 29 Nov 2003 22:40:59 -0000 1.22 --- src/include/commands/user.h 27 Jun 2004 21:33:02 -0000 *************** *** 32,36 **** --- 32,37 ---- extern Datum update_pg_pwd_and_pg_group(PG_FUNCTION_ARGS); extern void AtEOXact_UpdatePasswordFile(bool isCommit); + extern void AtEOSubXact_UpdatePasswordFile(bool isCommit); #endif /* USER_H */