tBOOL DelHash(DWHASH_TYPE *lpHash, tVOID *lpItem, tINT nDelInfo) { tINT nPos; DWHASH_BLOCK_TYPE HashItem; DWHASH_NEXT_TYPE NextItem; tINT i; nPos = lpHash->pHashCalFunc(lpItem); if (nPos < 0) nPos *= -1; if (nPos >= lpHash->nBucketCount) { // exception nPos %= lpHash->nBucketCount; } memcpy(&HashItem, lpHash->lpBuf + nPos*sizeof(DWHASH_BLOCK_TYPE), sizeof(DWHASH_BLOCK_TYPE)); if (HashItem.nInfo == nDelInfo) { // 처음 것을 지울 때.. if (HashItem.lpNextRec == NULL) { HashItem.nInfo = -1; memcpy(lpHash->lpBuf + nPos*sizeof(DWHASH_BLOCK_TYPE), &HashItem, sizeof(DWHASH_BLOCK_TYPE)); } else { // 첫번째 것을 세팅한다. GetRecord(HashItem.lpNextRec, 0, &NextItem); DelRecord(HashItem.lpNextRec, 0); HashItem.nInfo = NextItem.nInfo; if (HashItem.lpNextRec->nUsed == 0) { // clear하자 FreeRecord(HashItem.lpNextRec); free(HashItem.lpNextRec); HashItem.lpNextRec = NULL; } memcpy(lpHash->lpBuf + nPos*sizeof(DWHASH_BLOCK_TYPE), &HashItem, sizeof(DWHASH_BLOCK_TYPE)); if (lpHash->nCollision > 0) lpHash->nCollision --; } } else if (HashItem.lpNextRec) { // 더 있으면 더 찾아야지.. for ( i = 0 ; i < HashItem.lpNextRec->nUsed ; i ++ ) { GetRecord(HashItem.lpNextRec, i, &NextItem); if (NextItem.nInfo == nDelInfo) { DelRecord(HashItem.lpNextRec, i); if (lpHash->nCollision > 0) lpHash->nCollision --; break; } } if (HashItem.lpNextRec->nUsed == 0) { // clear하자 FreeRecord(HashItem.lpNextRec); free(HashItem.lpNextRec); HashItem.lpNextRec = NULL; memcpy(lpHash->lpBuf + nPos*sizeof(DWHASH_BLOCK_TYPE), &HashItem, sizeof(DWHASH_BLOCK_TYPE)); } } else { // not found return TRUE; } return TRUE; }
tBOOL DeleteThTime(pthread_t ThreadId) { #if defined(_USE_SAFETH) tINT nItem; SAFETH_FORMAT SafeItem; struct itimerval itimer; tINT last_state; if (!bStSafeTh) return TRUE; //pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &last_state); pthread_cleanup_push((tVOID *)pthread_mutex_unlock, (tVOID *)&gCheckTh); pthread_mutex_lock(&gCheckTh); SafeItem.ThreadId = ThreadId; nItem = FindRecord(&RecordThTime, &SafeItem, FALSE, (CompProcP)Comp_ThreadId); if (nItem == -1) { // 새로운 thread printf("not found.... maybe delete ... %d\n", ThreadId); } else { DelRecord(&RecordThTime, nItem); } //pthread_mutex_unlock(&gCheckTh); pthread_cleanup_pop(1); //pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &last_state); #endif return TRUE; }
void *malloc (size_t size) { frec_p frp, prev_frp; addrs_t frstart; size += 8; /* Allocate space for tracking size of actual allocation */ prev_frp = frp = frhead; while (frp) { if (frp->size >= (int)(ALIGN * ceil(size, ALIGN))) { /* Have found space. */ frstart = frp->fbp; frp->fbp += (int)(ALIGN * ceil(size, ALIGN)); frp->size -= (int)(ALIGN * ceil(size, ALIGN)); *((int *)frstart) = size; /* Store size allocated */ /* If block is only partially allocated then return. */ if (frp->size) return (frstart+8); /* Complete block is allocated. Adjust free record list. */ DelRecord (prev_frp, frp); return (frstart+8); } prev_frp = frp; frp = frp->next; } return NULL; }
static void MergeRecords (frec_p frp) { frec_p next_frp; /* Merge contiguous records if possible. */ if ((next_frp = frp->next) == NULL) return; if (frp->fbp + frp->size == next_frp->fbp) { frp->size += next_frp->size; DelRecord (frp, next_frp); } else frp = next_frp; if ((next_frp = frp->next) == NULL) return; if (frp->fbp + frp->size == next_frp->fbp) { frp->size += next_frp->size; DelRecord (frp, next_frp); } }
tINT RecoveryThPool(tVOID) { THPOOL_ITEMTYPE PoolItem; tINT i; struct timeval tv; double usec, sec; tINT nCount_RecoveryTh = 0; LockMutexMan(&gMutexThPool, ID_MUTEX_POOL); for ( i = 0 ; i < gTHPOOL.nUsed ; i ++ ) { GetRecord(&gTHPOOL, i, &PoolItem); if (PoolItem.bActive) { gettimeofday(&tv, NULL); usec = (double)tv.tv_usec - (double)PoolItem.tv.tv_usec; sec = (double)tv.tv_sec - (double)PoolItem.tv.tv_sec; if(usec < 0) { sec = sec - 1; usec = 1000000 + usec; } sec += (usec/(double)1000000); if (sec > gnDelayTimeOut) { printf("delay time(%f), kill %d\n", sec, (tINT)(PoolItem.ThreadId)); pthread_kill(PoolItem.ThreadId, SIGQUIT); if (PoolItem.nSocketId) close(PoolItem.nSocketId); DelRecord(&gTHPOOL, i); i --; nCount_RecoveryTh ++; continue; } } } UnLockMutexMan(&gMutexThPool, ID_MUTEX_POOL); for ( i = 0 ; i < nCount_RecoveryTh ; i ++ ) { if(CreateThread(NULL, gfProc_ThreadFunc_THPOOL, (tVOID *)(gnSocketId_THPOOL)) == FALSE) { printf("%d Thread Create Error\n", i); break; } else { printf("[recovery thread count : %d, total th count : %d] - %d Thread Create Ok\n", nCount_RecoveryTh, gnTotalThread_THPOOL, i); } } return (nCount_RecoveryTh); }
tVOID CheckIdleTimeTh(tVOID *lpParam) { #if defined(_USE_SAFETH) tINT i; SAFETH_FORMAT SafeItem; time_t t = time(NULL); // 현재 시간.. double dTime; tBOOL bCont = FALSE; tINT nCount = 0; tINT last_state; if (!bStSafeTh) return; pthread_cleanup_push((tVOID *)pthread_mutex_unlock, (tVOID *)&gCheckTh); pthread_mutex_lock(&gCheckTh); i = 0; while( i < RecordThTime.nUsed ) { GetRecord(&RecordThTime, i, &SafeItem); if (SafeItem.bBusy) { //printf("%d busy\n", SafeItem.ThreadId); i ++; continue; } t = time(NULL); // 현재 시간.. dTime = difftime(t, SafeItem.s_time); if (dTime >= (double)nIdleTimeSec) { printf("CancelThread : %d-%d\n", SafeItem.ThreadId, SafeItem.nSocketId); /* if (CancelThread(SafeItem.ThreadId) != 0) { printf("CancelThread Error.. %d\n", errno); } */ pthread_kill(SafeItem.ThreadId, SIGUSR1); // 잘 갔는지.. 기다려야지.. pthread_mutex_lock(&gSigMutex); pthread_cond_wait(&gSigCond, &gSigMutex); pthread_mutex_unlock(&gSigMutex); printf("OK Kill\n"); #if defined(_USE_SAFEMEM) DelSafeMem(SafeItem.ThreadId, TRUE); // memory를 다 free시키자. #endif DelSafeMutex(SafeItem.ThreadId, TRUE); if (SafeItem.nSocketId >= 0) close(SafeItem.nSocketId); // socket close해야지.. if (DelRecord(&RecordThTime, i)) { // 먼저 지워야지 다음에 안하지.. continue; } } i++; } /* if (pthread_mutex_unlock(&gCheckTh) != 0) { printf("unlock MUTEX_IDLE error...\n"); } */ pthread_cleanup_pop(1); #endif }