diff options
Diffstat (limited to 'src/backend/utils/init/miscinit.c')
-rw-r--r-- | src/backend/utils/init/miscinit.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index bf3871a774b..683f616b1a8 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -936,6 +936,99 @@ GetUserNameFromId(Oid roleid, bool noerr) return result; } +/* ------------------------------------------------------------------------ + * Client connection state shared with parallel workers + * + * ClientConnectionInfo contains pieces of information about the client that + * need to be synced to parallel workers when they initialize. + *------------------------------------------------------------------------- + */ + +ClientConnectionInfo MyClientConnectionInfo; + +/* + * Intermediate representation of ClientConnectionInfo for easier + * serialization. Variable-length fields are allocated right after this + * header. + */ +typedef struct SerializedClientConnectionInfo +{ + int32 authn_id_len; /* strlen(authn_id), or -1 if NULL */ + UserAuth auth_method; +} SerializedClientConnectionInfo; + +/* + * Calculate the space needed to serialize MyClientConnectionInfo. + */ +Size +EstimateClientConnectionInfoSpace(void) +{ + Size size = 0; + + size = add_size(size, sizeof(SerializedClientConnectionInfo)); + + if (MyClientConnectionInfo.authn_id) + size = add_size(size, strlen(MyClientConnectionInfo.authn_id) + 1); + + return size; +} + +/* + * Serialize MyClientConnectionInfo for use by parallel workers. + */ +void +SerializeClientConnectionInfo(Size maxsize, char *start_address) +{ + SerializedClientConnectionInfo serialized = {0}; + + serialized.authn_id_len = -1; + serialized.auth_method = MyClientConnectionInfo.auth_method; + + if (MyClientConnectionInfo.authn_id) + serialized.authn_id_len = strlen(MyClientConnectionInfo.authn_id); + + /* Copy serialized representation to buffer */ + Assert(maxsize >= sizeof(serialized)); + memcpy(start_address, &serialized, sizeof(serialized)); + + maxsize -= sizeof(serialized); + start_address += sizeof(serialized); + + /* Copy authn_id into the space after the struct */ + if (serialized.authn_id_len >= 0) + { + Assert(maxsize >= (serialized.authn_id_len + 1)); + memcpy(start_address, + MyClientConnectionInfo.authn_id, + /* include the NULL terminator to ease deserialization */ + serialized.authn_id_len + 1); + } +} + +/* + * Restore MyClientConnectionInfo from its serialized representation. + */ +void +RestoreClientConnectionInfo(char *conninfo) +{ + SerializedClientConnectionInfo serialized; + + memcpy(&serialized, conninfo, sizeof(serialized)); + + /* Copy the fields back into place */ + MyClientConnectionInfo.authn_id = NULL; + MyClientConnectionInfo.auth_method = serialized.auth_method; + + if (serialized.authn_id_len >= 0) + { + char *authn_id; + + authn_id = conninfo + sizeof(serialized); + MyClientConnectionInfo.authn_id = MemoryContextStrdup(TopMemoryContext, + authn_id); + } +} + /*------------------------------------------------------------------------- * Interlock-file support |