goto Error;
}
- QuicConfigurationAddRef(Configuration);
+ QuicConfigurationAddRef(Configuration, QUIC_CONF_REF_CONN_START_OP);
Oper->API_CALL.Context->Type = QUIC_API_TYPE_CONN_START;
Oper->API_CALL.Context->CONN_START.Configuration = Configuration;
Oper->API_CALL.Context->CONN_START.ServerName = ServerNameCopy;
goto Error;
}
- QuicConfigurationAddRef(Configuration);
+ QuicConfigurationAddRef(Configuration, QUIC_CONF_REF_CONN_SET_OP);
Oper->API_CALL.Context->Type = QUIC_API_TYPE_CONN_SET_CONFIGURATION;
Oper->API_CALL.Context->CONN_SET_CONFIGURATION.Configuration = Configuration;
Configuration->ClientContext = Context;
Configuration->Registration = Registration;
CxPlatRefInitialize(&Configuration->RefCount);
+#if DEBUG
+ CxPlatRefInitializeMultiple(Configuration->RefTypeBiasedCount, QUIC_CONF_REF_COUNT);
+ CxPlatRefIncrement(&Configuration->RefTypeBiasedCount[QUIC_CONF_REF_HANDLE]);
+#endif
Configuration->AlpnListLength = (uint16_t)AlpnListLength;
AlpnList = Configuration->AlpnList;
Error:
if (QUIC_FAILED(Status) && Configuration != NULL) {
+#if DEBUG
+ CXPLAT_DBG_ASSERT(!CxPlatRefDecrement(&Configuration->RefTypeBiasedCount[QUIC_CONF_REF_HANDLE]));
+#endif
CxPlatStorageClose(Configuration->AppSpecificStorage);
#ifdef QUIC_SILO
CxPlatStorageClose(Configuration->Storage);
QuicRegistrationRundownRelease(Configuration->Registration, QUIC_REG_REF_CONFIGURATION);
+#if DEBUG
+ for (uint32_t i = 0; i < QUIC_CONF_REF_COUNT; i++) {
+ CXPLAT_DBG_ASSERT(QuicReadLongPtrNoFence(&Configuration->RefTypeBiasedCount[i]) == 1);
+ }
+#endif
+
QuicTraceEvent(
ConfigurationDestroyed,
"[cnfg][%p] Destroyed",
if (Handle != NULL && Handle->Type == QUIC_HANDLE_TYPE_CONFIGURATION) {
#pragma prefast(suppress: __WARNING_25024, "Pointer cast already validated.")
- QuicConfigurationRelease((QUIC_CONFIGURATION*)Handle);
+ QuicConfigurationRelease((QUIC_CONFIGURATION*)Handle, QUIC_CONF_REF_HANDLE);
}
QuicTraceEvent(
(HQUIC)Configuration,
Configuration->ClientContext,
Status);
- QuicConfigurationRelease(Configuration);
+ QuicConfigurationRelease(Configuration, QUIC_CONF_REF_LOAD_CRED);
}
}
TlsCredFlags |= CXPLAT_TLS_CREDENTIAL_FLAG_DISABLE_RESUMPTION;
}
- QuicConfigurationAddRef(Configuration);
+ QuicConfigurationAddRef(Configuration, QUIC_CONF_REF_LOAD_CRED);
Status =
CxPlatTlsSecConfigCreate(
//
// Release ref for synchronous calls or asynchronous failures.
//
- QuicConfigurationRelease(Configuration);
+ QuicConfigurationRelease(Configuration, QUIC_CONF_REF_LOAD_CRED);
}
}
--*/
+//
+// The different kinds of references on a Configuration.
+//
+typedef enum QUIC_CONFIGURATION_REF {
+
+ QUIC_CONF_REF_HANDLE,
+ QUIC_CONF_REF_CONNECTION,
+ QUIC_CONF_REF_LOAD_CRED,
+ QUIC_CONF_REF_CONN_START_OP,
+ QUIC_CONF_REF_CONN_SET_OP,
+
+ QUIC_CONF_REF_COUNT
+} QUIC_CONFIGURATION_REF;
+
//
// Represents a set of TLS and QUIC configurations and settings.
//
//
CXPLAT_REF_COUNT RefCount;
+#if DEBUG
+ //
+ // Detailed ref counts.
+ // Note: These ref counts are biased by 1, so lowest they go is 1. It is an
+ // error for them to ever be zero.
+ //
+ CXPLAT_REF_COUNT RefTypeBiasedCount[QUIC_CONF_REF_COUNT];
+#endif
+
//
// The TLS security configurations.
//
QUIC_INLINE
void
QuicConfigurationAddRef(
- _In_ QUIC_CONFIGURATION* Configuration
+ _In_ QUIC_CONFIGURATION* Configuration,
+ _In_ QUIC_CONFIGURATION_REF Ref
)
{
CxPlatRefIncrement(&Configuration->RefCount);
+#if DEBUG
+ CxPlatRefIncrement(&Configuration->RefTypeBiasedCount[Ref]);
+#else
+ UNREFERENCED_PARAMETER(Ref);
+#endif
}
//
QUIC_INLINE
void
QuicConfigurationRelease(
- _In_ QUIC_CONFIGURATION* Configuration
+ _In_ QUIC_CONFIGURATION* Configuration,
+ _In_ QUIC_CONFIGURATION_REF Ref
)
{
+#if DEBUG
+ CXPLAT_DBG_ASSERT(!CxPlatRefDecrement(&Configuration->RefTypeBiasedCount[Ref]));
+#else
+ UNREFERENCED_PARAMETER(Ref);
+#endif
if (CxPlatRefDecrement(&Configuration->RefCount)) {
QuicConfigurationUninitialize(Configuration);
}
Silo = Connection->Configuration->Silo;
QuicSiloAddRef(Silo);
#endif
- QuicConfigurationRelease(Connection->Configuration);
+ QuicConfigurationRelease(Connection->Configuration, QUIC_CONF_REF_CONNECTION);
Connection->Configuration = NULL;
}
if (Connection->RemoteServerName != NULL) {
"Configuration set, %p",
Configuration);
- QuicConfigurationAddRef(Configuration);
+ QuicConfigurationAddRef(Configuration, QUIC_CONF_REF_CONNECTION);
QuicConfigurationAttachSilo(Configuration);
Connection->Configuration = Configuration;
if (Oper->Type == QUIC_OPER_TYPE_API_CALL) {
QUIC_API_CONTEXT* ApiCtx = Oper->API_CALL.Context;
if (ApiCtx->Type == QUIC_API_TYPE_CONN_START) {
- QuicConfigurationRelease(ApiCtx->CONN_START.Configuration);
+ QuicConfigurationRelease(ApiCtx->CONN_START.Configuration, QUIC_CONF_REF_CONN_START_OP);
if (ApiCtx->CONN_START.ServerName != NULL) {
CXPLAT_FREE(ApiCtx->CONN_START.ServerName, QUIC_POOL_SERVERNAME);
}
} else if (ApiCtx->Type == QUIC_API_TYPE_CONN_SET_CONFIGURATION) {
- QuicConfigurationRelease(ApiCtx->CONN_SET_CONFIGURATION.Configuration);
+ QuicConfigurationRelease(ApiCtx->CONN_SET_CONFIGURATION.Configuration, QUIC_CONF_REF_CONN_SET_OP);
} else if (ApiCtx->Type == QUIC_API_TYPE_CONN_SEND_RESUMPTION_TICKET) {
if (ApiCtx->CONN_SEND_RESUMPTION_TICKET.ResumptionAppData != NULL) {
CXPLAT_DBG_ASSERT(ApiCtx->CONN_SEND_RESUMPTION_TICKET.AppDataLength != 0);