一. 哈希表
定义文件路径:quic_hashtable.h
QUIC_STREAM_SET哈希表指针:CXPLAT_HASHTABLE* StreamTable;
QUIC_STREAM定义元素:CXPLAT_HASHTABLE_ENTRY TableEntry;
1. initialize
if (StreamSet->StreamTable == NULL) {//// Lazily initialize the hash table.//if (!CxPlatHashtableInitialize(&StreamSet->StreamTable, CXPLAT_HASH_MIN_SIZE)) {QuicTraceEvent(AllocFailure,"Allocation of '%s' failed. (%llu bytes)","streamset hash table",0);return FALSE;}}
2. uninitialize
if (StreamSet->StreamTable != NULL) {CxPlatHashtableUninitialize(StreamSet->StreamTable);}
3. insert
CxPlatHashtableInsert(StreamSet->StreamTable, &Stream->TableEntry, (uint32_t)Stream->ID, NULL);
4. remove
CxPlatHashtableRemove(StreamSet->StreamTable, &Stream->TableEntry, NULL);
5. lookup
if (StreamSet->StreamTable == NULL) {return NULL; // No streams have been created yet.}CXPLAT_HASHTABLE_LOOKUP_CONTEXT Context;CXPLAT_HASHTABLE_ENTRY* Entry =CxPlatHashtableLookup(StreamSet->StreamTable, (uint32_t)ID, &Context);while (Entry != NULL) {QUIC_STREAM* Stream =CXPLAT_CONTAINING_RECORD(Entry, QUIC_STREAM, TableEntry);if (Stream->ID == ID) {return Stream;}Entry = CxPlatHashtableLookupNext(StreamSet->StreamTable, &Context);}return NULL;
6. for_each
if (StreamSet->StreamTable == NULL) {return; // No streams have been created yet.}CXPLAT_HASHTABLE_ENUMERATOR Enumerator;CXPLAT_HASHTABLE_ENTRY* Entry;CxPlatHashtableEnumerateBegin(StreamSet->StreamTable, &Enumerator);while ((Entry = CxPlatHashtableEnumerateNext(StreamSet->StreamTable, &Enumerator)) != NULL) {QuicStreamTraceRundown(CXPLAT_CONTAINING_RECORD(Entry, QUIC_STREAM, TableEntry));}CxPlatHashtableEnumerateEnd(StreamSet->StreamTable, &Enumerator);
二. 链表
定义文件路径:quic_platform.h
QUIC_SEND定义链表:CXPLAT_LIST_ENTRY SendStreams;
QUIC_STREAM元素指针:CXPLAT_LIST_ENTRY SendLink;
1. insert/for
CxPlatListInsertTail(&Connection->DestCids, &Path->DestCid->Link);for (CXPLAT_LIST_ENTRY* Entry = Connection->DestCids.Flink;Entry != &Connection->DestCids;Entry = Entry->Flink) {const QUIC_CID_LIST_ENTRY* DestCid =CXPLAT_CONTAINING_RECORD(Entry,QUIC_CID_LIST_ENTRY,Link);UNREFERENCED_PARAMETER(DestCid);QuicTraceEvent(ConnDestCidAdded,"[conn][%p] (SeqNum=%llu) New Destination CID: %!CID!",Connection,DestCid->CID.SequenceNumber,CASTED_CLOG_BYTEARRAY(DestCid->CID.Length, DestCid->CID.Data));}
CXPLAT_DBG_ASSERT(Stream->SendLink.Flink == NULL);CXPLAT_LIST_ENTRY* Entry = Send->SendStreams.Blink;while (Entry != &Send->SendStreams) {//// Search back to front for the right place (based on priority) to// insert the stream.//if (Stream->SendPriority <=CXPLAT_CONTAINING_RECORD(Entry, QUIC_STREAM, SendLink)->SendPriority) {break;}Entry = Entry->Blink;}CxPlatListInsertHead(Entry, &Stream->SendLink); // Insert after current Entry
2. remove
CxPlatListEntryRemove(&Stream->SendLink);Stream->SendLink.Flink = NULL;QuicStreamRelease(Stream, QUIC_STREAM_REF_SEND);Stream = NULL;
三. 锁
定义文件路径:quic_platform_posix.h (实际实现是pthread_mutex_t)
QUIC_LIBRARY链表指针:CXPLAT_LOCK Lock;
1. initCxPlatLockInitialize(&MsQuicLib.Lock);2. uninitCxPlatLockUninitialize(&MsQuicLib.Lock);3. lockCxPlatLockAcquire(&MsQuicLib.Lock);4. unlockCxPlatLockRelease(&MsQuicLib.Lock);
四. 线程
# 当前线程 (9993423)CXPLAT_THREAD_ID ThreadID = CxPlatCurThreadID();# 线程索引 (0、1、2、3)uint32_t CurProcIndex = CxPlatProcCurrentNumber();实现方式:(uint32_t)sched_getcpu() % CxPlatProcessorCount;# 所有worker线程数 (cpu核心数)MsQuicLib.ProcessorCount = (uint16_t)CxPlatProcActiveCount();MsQuicLib.ProcessorCount = (uint16_t)sysconf(_SC_NPROCESSORS_ONLN);
五. 时间
# 毫秒msint64_t Now = CxPlatTimeEpochMs64();
六. 内存池
- 接口
定义文件路径:quic_platform_posix.h
QUIC_WORKER指针:CXPLAT_POOL StreamPool;
1. initinlinevoidCxPlatPoolInitialize(_In_ BOOLEAN IsPaged,_In_ uint32_t Size,_In_ uint32_t Tag,_Inout_ CXPLAT_POOL* Pool)#define QUIC_POOL_STREAM '30cQ' // Qc03 - QUIC streamCxPlatPoolInitialize(FALSE, sizeof(QUIC_STREAM), QUIC_POOL_STREAM, &Worker->StreamPool);2. uninitCxPlatPoolUninitialize(&Worker->StreamPool);3. allocStream = CxPlatPoolAlloc(&Worker->StreamPool);if (Stream == NULL) {Status = QUIC_STATUS_OUT_OF_MEMORY;goto Exit;}CxPlatZeroMemory(Stream, sizeof(QUIC_STREAM));4. freeCxPlatPoolFree(&Worker->StreamPool, Stream);
从StreamPool中获取stream
QuicStreamInitialize QuicStreamFree
<a name="semW4"></a># 七. 引用计数定义文件路径:quic_platform_posix.h<br />QUIC_STREAM定义:CXPLAT_REF_COUNT RefCount;```c# initStream->RefCount = 1;CxPlatRefInitialize(&Stream->RefCount);# uninitCxPlatRefUninitialize(&Stream->RefCount);# incCxPlatRefIncrement(&Stream->RefCount);# decif (CxPlatRefDecrement(&Stream->RefCount)) {QuicStreamFree(Stream);return TRUE;}return FALSE;
八. 随机数
CxPlatRandom(sizeof(uint32_t), &Binding->RandomReservedVersion);
九. 宏定义
在frame.h、connection.c(QuicErrorCodeToStatus)、msquic_posix.h、/usr/include/asm-generic/error.h
十. 信号
定义文件路径:quic_platform_posix.h,实现是 pthread_cond_wait 和 pthread_cond_broadcast
#define CxPlatEventWaitForever(Event) CxPlatInternalEventWaitForever(&Event)#define CxPlatEventSet(Event) CxPlatInternalEventSet(&Event)
