void TransferCaptaincyUpdate(void) { udword numPackets; udword sizeofPacket; ubyte *packet; ubyte *copypacket; if ((transferCaptaincyDisabled) || (sigsNumPlayers < 2)) { return; } TimeoutTimerUpdateAll(); LockQueue(&ProcessCaptaincyPktQ); numPackets = queueNumberEntries(ProcessCaptaincyPktQ); while (numPackets > 0) { sizeofPacket = Dequeue(&ProcessCaptaincyPktQ,&packet); dbgAssert(sizeofPacket > 0); copypacket = memAlloc(sizeofPacket,"cp(miscpacket)",Pyrophoric); memcpy(copypacket,packet,sizeofPacket); UnLockQueue(&ProcessCaptaincyPktQ); dbgAssert(((HWPacketHeader *)copypacket)->type == PACKETTYPE_TRANSFERCAPTAINCY); ProcessTransferCaptaincyPacket((TransferCaptaincyPacket *)copypacket); memFree(copypacket); LockQueue(&ProcessCaptaincyPktQ); numPackets = queueNumberEntries(ProcessCaptaincyPktQ); } UnLockQueue(&ProcessCaptaincyPktQ); #if 0 if (numPackets == 0) { UnLockQueue(&ProcessCaptaincyPktQ); } else { sizeofPacket = Dequeue(&ProcessCaptaincyPktQ,&packet); dbgAssert(sizeofPacket > 0); copypacket = memAlloc(sizeofPacket,"cp(miscpacket)",Pyrophoric); memcpy(copypacket,packet,sizeofPacket); UnLockQueue(&ProcessCaptaincyPktQ); dbgAssert(((HWPacketHeader *)copypacket)->type == PACKETTYPE_TRANSFERCAPTAINCY); ProcessTransferCaptaincyPacket((TransferCaptaincyPacket *)copypacket); memFree(copypacket); } #endif }
// パケットアダプタの解放 void LinkPaFree(SESSION *s) { LINK *k; // 引数チェック if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return; } // サーバーセッションの停止 StopSession(k->ServerSession); ReleaseSession(k->ServerSession); // 送信パケットキューの解放 LockQueue(k->SendPacketQueue); { BLOCK *block; while (block = GetNext(k->SendPacketQueue)) { FreeBlock(block); } } UnlockQueue(k->SendPacketQueue); ReleaseQueue(k->SendPacketQueue); }
// //Finds the first occurrence of a queue element based on the predicate and //removes it from the queue // QueueElementData Queue_RemoveElement(PQueue pQueue, void * predicate, DoesMatch pDoesMatchFunc) { QueueElementData data = NULL; PQueueElement currItem = NULL; if(!pQueue) { return NULL; } LockQueue(pQueue); if (NULL == pQueue->pHead) { UnLockQueue(pQueue); return NULL; } currItem = pQueue->pHead; while (currItem != NULL) { if (pDoesMatchFunc(currItem->data, predicate) == TRUE) { data = Queue_RemoveElementInternal(pQueue, currItem); break; } currItem = currItem->pNextItem; } UnLockQueue(pQueue); return data; }
extern Bool EnQueue( Queue *que, void *data) { QueueElement *el; Bool rc; ENTER_FUNC; if ( ( que != NULL ) && ( LockQueue(que) == 0 ) ) { el = New(QueueElement); el->data = data; el->prev = que->tail; el->next = NULL; if ( que->tail == NULL ) { que->head = el; } else { que->tail->next = el; } que->tail = el; que->length++; UnLockQueue(que); ReleaseQueue(que); rc = TRUE; } else { rc = FALSE; } LEAVE_FUNC; return (rc); }
// Get the next packet UINT LinkPaGetNextPacket(SESSION *s, void **data) { LINK *k; UINT ret = 0; // Validate arguments if (s == NULL || data == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return INFINITE; } // Examine whether there are packets in the queue LockQueue(k->SendPacketQueue); { BLOCK *block = GetNext(k->SendPacketQueue); if (block != NULL) { // There was a packet *data = block->Buf; ret = block->Size; // Discard the memory for the structure Free(block); } } UnlockQueue(k->SendPacketQueue); return ret; }
// Release the packet adapter void LinkPaFree(SESSION *s) { LINK *k; // Validate arguments if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return; } // Stop the server session StopSession(k->ServerSession); ReleaseSession(k->ServerSession); // Release the transmission packet queue LockQueue(k->SendPacketQueue); { BLOCK *block; while (block = GetNext(k->SendPacketQueue)) { FreeBlock(block); } } UnlockQueue(k->SendPacketQueue); ReleaseQueue(k->SendPacketQueue); }
static SrvJob *GetCurrentJob() { SrvJob *job; LockQueue(); job = CurrentJob; return job; }
// 次のパケットを取得 UINT LinkPaGetNextPacket(SESSION *s, void **data) { LINK *k; UINT ret = 0; // 引数チェック if (s == NULL || data == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return INFINITE; } // キューにパケットが溜まっているかどうか調べる LockQueue(k->SendPacketQueue); { BLOCK *block = GetNext(k->SendPacketQueue); if (block != NULL) { // パケットがあった *data = block->Buf; ret = block->Size; // 構造体のメモリは破棄する Free(block); } } UnlockQueue(k->SendPacketQueue); return ret; }
extern void * DeQueueNoWait( Queue *que) { QueueElement *el; void *ret; ENTER_FUNC; if ( ( que != NULL ) && ( que->head != NULL ) && ( LockQueue(que) == 0 )) { el = que->head; if ( el->next == NULL ) { que->tail = NULL; } else { el->next->prev = NULL; } que->head = el->next; ret = el->data; xfree(el); UnLockQueue(que); } else { ret = NULL; } LEAVE_FUNC; return (ret); }
// Release void NullPaFree(SESSION *s) { // Validate arguments NULL_LAN *n; BLOCK *b; if (s == NULL || (n = s->PacketAdapter->Param) == NULL) { return; } n->Halt = true; Set(n->Event); WaitThread(n->PacketGeneratorThread, INFINITE); ReleaseThread(n->PacketGeneratorThread); LockQueue(n->PacketQueue); { while (b = GetNext(n->PacketQueue)) { FreeBlock(b); } } UnlockQueue(n->PacketQueue); ReleaseQueue(n->PacketQueue); ReleaseCancel(n->Cancel); ReleaseEvent(n->Event); s->PacketAdapter->Param = NULL; Free(n); }
extern void OpenQueue( Queue *que) { LockQueue(que); que->curr = NULL; }
static int RemoveLast() { SrvJob *job; int status; LockQueue(); job = LastQueueEntry; if (job) { LastQueueEntry = job->h.previous; if(LastQueueEntry) LastQueueEntry->h.next = 0; else FirstQueueEntry = 0; FreeJob(job); printf("Removed pending action"); status = 1; } else { status = 0; } UnlockQueue(); return status; }
QueueElementData Queue_Dequeue(PQueue pQueue) { QueueElement *qElm; QueueElementData data; if(!pQueue) return NULL; LockQueue(pQueue); if (NULL == pQueue->pHead) { UnLockQueue(pQueue); return NULL; } qElm = pQueue->pHead; pQueue->pHead = qElm->pNextItem; if (NULL == qElm->pNextItem)//there is only one element { pQueue->pTail = NULL; } data = qElm->data; free(qElm); qElm = NULL; pQueue->dwCount--; UnLockQueue(pQueue); return data; }
extern void * DeQueueTime( Queue *que, int ms) { QueueElement *el; void *ret; ENTER_FUNC; if ( ( que != NULL ) && ( LockQueue(que) == 0 ) ) { WaitQueueTime(que,ms); if ( ( el = que->head ) != NULL ) { if ( el->next == NULL ) { que->tail = NULL; } else { el->next->prev = NULL; } que->head = el->next; ret = el->data; xfree(el); que->length--; } else { ret = NULL; } UnLockQueue(que); } else { ret = NULL; } LEAVE_FUNC; return (ret); }
BOOL Queue_Enqueue(PQueue pQueue, QueueElementData item) { QueueElement *qElm; if(!pQueue) return FALSE; //Create new queue element and add it to the tail. qElm = (QueueElement*)malloc( sizeof(QueueElement) ); if (NULL == qElm) { return FALSE; } qElm->data = item; qElm->pNextItem = NULL; LockQueue(pQueue); qElm->pPrevItem = pQueue->pTail; if (NULL == pQueue->pTail)//this is the first element { pQueue->pTail = pQueue->pHead = qElm; } else { pQueue->pTail->pNextItem = qElm; pQueue->pTail = qElm; } pQueue->dwCount++; UnLockQueue(pQueue); return TRUE; }
UINT EthGetPacketBpf(ETH *e, void **data) { struct CAPTUREBLOCK *block; UINT size; LockQueue(e->Queue); block = GetNext(e->Queue); if(block != NULL){ e->QueueSize -= block->Size; } UnlockQueue(e->Queue); if(block == NULL){ *data = NULL; if(e->Socket == INVALID_SOCKET){ return INFINITE; } return 0; } *data = block->Buf; size = block->Size; FreeCaptureBlock(block); return size; }
// Packet generation thread void NullPacketGenerateThread(THREAD *t, void *param) { NULL_LAN *n = (NULL_LAN *)param; // Validate arguments if (t == NULL || param == NULL) { return; } while (true) { Wait(n->Event, Rand32() % NULL_PACKET_GENERATE_INTERVAL); if (n->Halt) { break; } LockQueue(n->PacketQueue); { UCHAR *data; BLOCK *b; UINT size = Rand32() % 1500 + 14; data = Malloc(size); Copy(data, null_lan_broadcast_address, 6); Copy(data + 6, n->MacAddr, 6); b = NewBlock(data, size, 0); InsertQueue(n->PacketQueue, b); } UnlockQueue(n->PacketQueue); Cancel(n->Cancel); } }
// Get the next packet UINT NullPaGetNextPacket(SESSION *s, void **data) { UINT size = 0; // Validate arguments NULL_LAN *n; if (s == NULL || (n = s->PacketAdapter->Param) == NULL) { return INFINITE; } LockQueue(n->PacketQueue); { BLOCK *b = GetNext(n->PacketQueue); if (b != NULL) { *data = b->Buf; size = b->Size; Free(b); } } UnlockQueue(n->PacketQueue); return size; }
// Release the packet adapter void LinkPaFree(SESSION *s) { LINK *k; // Validate arguments if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return; } CedarAddQueueBudget(k->Cedar, -((int)k->LastServerConnectionReceivedBlocksNum)); k->LastServerConnectionReceivedBlocksNum = 0; // Stop the server session StopSession(k->ServerSession); ReleaseSession(k->ServerSession); // Release the transmission packet queue LockQueue(k->SendPacketQueue); { BLOCK *block; while (block = GetNext(k->SendPacketQueue)) { FreeBlock(block); } } UnlockQueue(k->SendPacketQueue); ReleaseQueue(k->SendPacketQueue); k->CurrentSendPacketQueueSize = 0; }
// BPF でのパケットキャプチャの中継用スレッド void BpfThread(THREAD *thread, void *param) { ETH *e = (ETH*)param; int fd = e->Socket; int len; int rest; // バッファ中の残りバイト数 UCHAR *next; //バッファ中の次のパケットの先頭 struct CAPTUREBLOCK *block; // キューに追加するデータ UCHAR *data; struct bpf_hdr *hdr; // バッファを確保 UCHAR *buf = Malloc(e->BufSize); // 初期化完了を通知 NoticeThreadInit(thread); while(1){ // ループの脱出判定 if(e->Socket == INVALID_SOCKET){ break; } rest = read(fd, buf, e->BufSize); if(rest < 0 && errno != EAGAIN){ // エラー close(fd); e->Socket = INVALID_SOCKET; Free(buf); Cancel(e->Cancel); return; } next = buf; LockQueue(e->Queue); while(rest>0){ // パケットの切り出し hdr = (struct bpf_hdr*)next; // Queue中のパケットサイズが限界を超えたらパケットを破棄する if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){ data = Malloc(hdr->bh_caplen); Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen); block = NewCaptureBlock(data, hdr->bh_caplen); InsertQueue(e->Queue, block); e->QueueSize += hdr->bh_caplen; } // 次のパケットの頭出し rest -= BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen); next += BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen); } UnlockQueue(e->Queue); Cancel(e->Cancel); } Free(buf); Cancel(e->Cancel); return; }
// Relay thread for captured packet (BPF) void BpfThread(THREAD *thread, void *param) { ETH *e = (ETH*)param; int fd = e->Socket; int len; int rest; // Rest size in buffer UCHAR *next; // Head of next packet in buffer struct CAPTUREBLOCK *block; // Data to enqueue UCHAR *data; struct bpf_hdr *hdr; // Allocate the buffer UCHAR *buf = Malloc(e->BufSize); // Notify initialize completed NoticeThreadInit(thread); while(1){ // Determining to exit loop if(e->Socket == INVALID_SOCKET){ break; } rest = read(fd, buf, e->BufSize); if(rest < 0 && errno != EAGAIN){ // Error close(fd); e->Socket = INVALID_SOCKET; Free(buf); Cancel(e->Cancel); return; } next = buf; LockQueue(e->Queue); while(rest>0){ // Cut out a packet hdr = (struct bpf_hdr*)next; // Discard arriving packet when queue filled if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){ data = Malloc(hdr->bh_caplen); Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen); block = NewCaptureBlock(data, hdr->bh_caplen); InsertQueue(e->Queue, block); e->QueueSize += hdr->bh_caplen; } // Find the head of next packet rest -= BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen); next += BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen); } UnlockQueue(e->Queue); Cancel(e->Cancel); } Free(buf); Cancel(e->Cancel); return; }
int32 FChunkCacheWorker::ProcessQueue() { SCOPE_CYCLE_COUNTER( STAT_FChunkCacheWorker_ProcessQueue ); // Add the queue to the active requests list { FScopeLock LockQueue(&QueueLock); ActiveRequests.Append(RequestQueue); RequestQueue.Empty(); } // Keep track how many request have been process this loop int32 ProcessedRequests = ActiveRequests.Num(); for (int32 RequestIndex = 0; RequestIndex < ActiveRequests.Num(); ++RequestIndex) { FChunkRequest& Request = *ActiveRequests[RequestIndex]; if (Request.RefCount.GetValue() == 0) { // ChunkRequest is no longer used by anything. Add it to the free requests lists // and release the associated buffer. ReleaseBuffer(Request.Index); ActiveRequests.RemoveAt(RequestIndex--); FreeChunkRequests.Push(&Request); } else if (Request.Buffer == NULL) { // See if the requested chunk is already cached. FChunkBuffer* CachedBuffer = GetCachedChunkBuffer(Request.Index); if (!CachedBuffer) { // This chunk is not cached. Get a free buffer if possible. CachedBuffer = GetFreeBuffer(); if (!!CachedBuffer) { // Load and verify. CachedBuffer->ChunkIndex = Request.Index; Request.Buffer = CachedBuffer; CheckSignature(Request); } } else { Request.Buffer = CachedBuffer; } if (!!CachedBuffer) { check(Request.Buffer == CachedBuffer); // Chunk is cached and trusted. We no longer need the request handle on this thread. // Let the other thread know the chunk is ready to read. Request.RefCount.Decrement(); Request.IsTrusted.Increment(); } } } return ProcessedRequests; }
// //Removes a specified element from the queue // static QueueElementData Queue_RemoveElementInternal(PQueue pQueue, PQueueElement pQueueElem) { QueueElementData data; PQueueElement prevItem = pQueueElem->pPrevItem; PQueueElement nextItem = pQueueElem->pNextItem; if(!pQueue) { return NULL; } LockQueue(pQueue); if (NULL == pQueue->pHead) { UnLockQueue(pQueue); return NULL; } //Connect prevItem to nextItem if (prevItem != NULL) { prevItem->pNextItem = nextItem; } else { //pQueueElem is the queue head pQueue->pHead = nextItem; } //Connect nextItem to prevItem if (nextItem != NULL) { nextItem->pPrevItem = prevItem; } else { //pQueueElem is the queue tail pQueue->pTail = prevItem; } //Extract data and return... data = pQueueElem->data; free(pQueueElem); pQueueElem = NULL; pQueue->dwCount--; UnLockQueue(pQueue); return data; }
static int QJob(SrvJob *job) { SrvJob *qjob = (SrvJob *)memcpy(malloc(job->h.length),job,job->h.length); LockQueue(); if (LastQueueEntry != 0) LastQueueEntry->h.next = qjob; qjob->h.next = 0; qjob->h.previous = LastQueueEntry; LastQueueEntry = qjob; if (FirstQueueEntry == 0) FirstQueueEntry = qjob; UnlockQueue(); return StartThread(); }
// Packet generation thread void NullPacketGenerateThread(THREAD *t, void *param) { NULL_LAN *n = (NULL_LAN *)param; UINT64 end_tick = Tick64() + (UINT64)(60 * 1000); UINT seq = 0; // Validate arguments if (t == NULL || param == NULL) { return; } while (true) { /*if (Tick64() >= end_tick) { break; }*/ Wait(n->Event, Rand32() % 1500); if (n->Halt) { break; } LockQueue(n->PacketQueue); { UCHAR *data; BLOCK *b; UINT size = Rand32() % 1500 + 14; UCHAR dst_mac[6]; NullGenerateMacAddress(n->MacAddr, n->Id, seq); //NullGenerateMacAddress(dst_mac, n->Id + 1, 0); //StrToMac(dst_mac, "00-1B-21-A9-47-E6"); StrToMac(dst_mac, "00-AC-7A-EF-83-FD"); data = Malloc(size); Copy(data, null_lan_broadcast_address, 6); //Copy(data, dst_mac, 6); Copy(data + 6, n->MacAddr, 6); b = NewBlock(data, size, 0); InsertQueue(n->PacketQueue, b); } UnlockQueue(n->PacketQueue); Cancel(n->Cancel); //seq++; } }
int Queue_Count(PQueue pQueue) { UINT32 count; if(!pQueue) return 0; LockQueue(pQueue); count = pQueue->dwCount; UnLockQueue(pQueue); return count; }
bool Frontend::ServerEditQueue(DownloadQueue::EEditAction eAction, int iOffset, int iID) { if (IsRemoteMode()) { return RequestEditQueue(eAction, iOffset, iID); } else { DownloadQueue* pDownloadQueue = LockQueue(); bool bOK = pDownloadQueue->EditEntry(iID, eAction, iOffset, NULL); UnlockQueue(); return bOK; } return false; }
static SrvJob *LastJob() { SrvJob *job; LockQueue(); job = LastQueueEntry; if (job) { LastQueueEntry = job->h.previous; if(LastQueueEntry) LastQueueEntry->h.next = 0; else FirstQueueEntry = 0; } UnlockQueue(); return job; }
// パケット到着のコールバック関数 void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) { ETH *e = (ETH*) user; struct CAPTUREBLOCK *block; UCHAR *data; data = Malloc(h->caplen); Copy(data, bytes, h->caplen); block = NewCaptureBlock(data, h->caplen); LockQueue(e->Queue); // キューのサイズが限界を超えたらパケットを破棄する。 if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){ InsertQueue(e->Queue, block); e->QueueSize += h->caplen; } UnlockQueue(e->Queue); Cancel(e->Cancel); return; }
// Callback function to receive arriving packet (Pcap) void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) { ETH *e = (ETH*) user; struct CAPTUREBLOCK *block; UCHAR *data; data = Malloc(h->caplen); Copy(data, bytes, h->caplen); block = NewCaptureBlock(data, h->caplen); LockQueue(e->Queue); // Discard arriving packet when queue filled if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){ InsertQueue(e->Queue, block); e->QueueSize += h->caplen; } UnlockQueue(e->Queue); Cancel(e->Cancel); return; }