static int pset_create(psetid_t *psetp) { psetid_t newpset; int error; if (secpolicy_pset(CRED()) != 0) return (set_errno(EPERM)); pool_lock(); if (pool_state == POOL_ENABLED) { pool_unlock(); return (set_errno(ENOTSUP)); } error = cpupart_create(&newpset); if (error) { pool_unlock(); return (set_errno(error)); } if (copyout(&newpset, psetp, sizeof (psetid_t)) != 0) { (void) cpupart_destroy(newpset); pool_unlock(); return (set_errno(EFAULT)); } pool_unlock(); return (error); }
/* * scan pool for matching idle slot * locks slot and returns index if found, * (-1 - clones located) if not found */ int pool_scan_idle(pool_t* pool, char* name) { int i; int found = -1; int clones = 0; slot_t* slot = NULL; pool_lock(pool); for (i = 0; i < pool->count; i++) { slot = pool_slot(pool, i); /* do the names match and is it a valid state? */ if (((!name && !slot->name) || ((name && slot->name) && (strcmp(name, slot->name) == 0))) && slot->state) { #ifdef CHATTER logit("\t\tfound script '%s' in state [%d]", name, i); #endif /* count the clones */ clones++; /* is the slot available? */ if (!slot->status) { /* lock it */ slot->access = time(NULL); slot->count++; slot->status = STATUS_BUSY; found = i; break; } } } pool_unlock(pool); if (found > -1) { return found; } else { return found - clones; } }
/* * scan pool for free slot * if no free slots then flush quietest one, * locks slot and returns index if found, * -1 if not found */ int pool_scan_free(pool_t* pool) { int i; int found = -1; int access = 0; slot_t* slot = NULL; pool_lock(pool); for (i = 0; i < pool->count; i++) { slot = pool_slot(pool, i); if (!slot->status) { if (!slot->state) { found = i; break; } else { if ((access == 0) || (slot->access < access)) { access = slot->access; found = i; } } } } if (found >= 0) { /* no free slots found, flush the quietest one */ if (i == pool->count) pool_flush(pool, found); /* lock it up */ (pool_slot(pool, found))->status = STATUS_BUSY; } pool_unlock(pool); return found; }
void mem_pool::pool_print( CLogger* log ) { int i, j; mempage_t* curr; for( i = 0; i < MEMORY_POOL_LISTS; ++i ) { if( !(pool[i].first) ) continue; if( pool_lock ) pool_lock( i ); log->DumpVar( "\npool[%d] chunk = %d", i, BLOCK_SIZE(i) ); log->DumpVar( "\n\tpool[%d].page_size = %lu", i, (unsigned long)pool[i].page_size ); log->DumpVar( "\n\tpool[%d].useable = %lu", i, (unsigned long)pool[i].useable ); for( j = 0; j < MEMORY_POOL_BUFFER; ++j ) log->DumpVar( "\n\tpool[%d].buffer[%d] = %p", i, j, pool[i].buffer[j] ); log->DumpVar( "\n\tpool[%d].first = %p: ", i, pool[i].first ); curr = pool[i].first; while( curr ) { log->DumpVar( "\n\tnext = %p | count = %lu | free = %p", curr->next, (unsigned long)curr->count, curr->free ); curr = curr->next; } if( pool_unlock ) pool_unlock( i ); } }
static void sfree_pool(struct pool *pool, void *ptr) { struct block_hdr *hdr; unsigned int i, idx; unsigned long offset; if (!ptr) return; ptr -= sizeof(*hdr); hdr = ptr; assert(ptr_valid(pool, ptr)); sfree_check_redzone(hdr); offset = ptr - pool->map; i = offset / SMALLOC_BPL; idx = (offset % SMALLOC_BPL) / SMALLOC_BPB; pool_lock(pool); clear_blocks(pool, i, idx, size_to_blocks(hdr->size)); if (i < pool->next_non_full) pool->next_non_full = i; pool->free_blocks += size_to_blocks(hdr->size); pool_unlock(pool); }
/* * Bind the lwp:id of process:pid to processor set: pset */ static int pset_bind_lwp(psetid_t pset, id_t id, pid_t pid, psetid_t *opset) { kthread_t *tp; proc_t *pp; psetid_t oldpset; void *projbuf, *zonebuf; int error = 0; pool_lock(); mutex_enter(&cpu_lock); projbuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_PROJ); zonebuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_ZONE); mutex_enter(&pidlock); if ((pid == P_MYID && id == P_MYID) || (pid == curproc->p_pid && id == P_MYID)) { pp = curproc; tp = curthread; mutex_enter(&pp->p_lock); } else { if (pid == P_MYID) { pp = curproc; } else if ((pp = prfind(pid)) == NULL) { error = ESRCH; goto err; } if (pp != curproc && id == P_MYID) { error = EINVAL; goto err; } mutex_enter(&pp->p_lock); if ((tp = idtot(pp, id)) == NULL) { mutex_exit(&pp->p_lock); error = ESRCH; goto err; } } error = pset_bind_thread(tp, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pp->p_lock); err: mutex_exit(&pidlock); fss_freebuf(projbuf, FSS_ALLOC_PROJ); fss_freebuf(zonebuf, FSS_ALLOC_ZONE); mutex_exit(&cpu_lock); pool_unlock(); if (opset != NULL) { if (copyout(&oldpset, opset, sizeof (psetid_t)) != 0) return (set_errno(EFAULT)); } if (error != 0) return (set_errno(error)); return (0); }
static int pset_destroy(psetid_t pset) { int error; if (secpolicy_pset(CRED()) != 0) return (set_errno(EPERM)); pool_lock(); if (pool_state == POOL_ENABLED) { pool_unlock(); return (set_errno(ENOTSUP)); } error = cpupart_destroy(pset); pool_unlock(); if (error) return (set_errno(error)); else return (0); }
static void *__smalloc_pool(struct pool *pool, size_t size) { size_t nr_blocks; unsigned int i; unsigned int offset; unsigned int last_idx; void *ret = NULL; pool_lock(pool); nr_blocks = size_to_blocks(size); if (nr_blocks > pool->free_blocks) goto fail; i = pool->next_non_full; last_idx = 0; offset = -1U; while (i < pool->nr_blocks) { unsigned int idx; if (pool->bitmap[i] == -1U) { i++; pool->next_non_full = i; last_idx = 0; continue; } idx = find_next_zero(pool->bitmap[i], last_idx); if (!blocks_free(pool, i, idx, nr_blocks)) { idx += nr_blocks; if (idx < SMALLOC_BPI) last_idx = idx; else { last_idx = 0; while (idx >= SMALLOC_BPI) { i++; idx -= SMALLOC_BPI; } } continue; } set_blocks(pool, i, idx, nr_blocks); offset = i * SMALLOC_BPL + idx * SMALLOC_BPB; break; } if (i < pool->nr_blocks) { pool->free_blocks -= nr_blocks; ret = pool->map + offset; } fail: pool_unlock(pool); return ret; }
void pool_close(pool_t* pool) { int i = 0; if (pool) { // dealloc pool pool_lock(pool); for (i = 0; i < pool->count; i++) pool_flush(pool, i); pool_unlock(pool); if (pool->slot) free(pool->slot); free(pool); } }
static int pset_assign(psetid_t pset, processorid_t cpuid, psetid_t *opset, int forced) { psetid_t oldpset; int error = 0; cpu_t *cp; if (pset != PS_QUERY && secpolicy_pset(CRED()) != 0) return (set_errno(EPERM)); pool_lock(); if (pset != PS_QUERY && pool_state == POOL_ENABLED) { pool_unlock(); return (set_errno(ENOTSUP)); } mutex_enter(&cpu_lock); if ((cp = cpu_get(cpuid)) == NULL) { mutex_exit(&cpu_lock); pool_unlock(); return (set_errno(EINVAL)); } oldpset = cpupart_query_cpu(cp); if (pset != PS_QUERY) error = cpupart_attach_cpu(pset, cp, forced); mutex_exit(&cpu_lock); pool_unlock(); if (error) return (set_errno(error)); if (opset != NULL) if (copyout(&oldpset, opset, sizeof (psetid_t)) != 0) return (set_errno(EFAULT)); return (0); }
void mem_pool::pool_free( void* ptr, size_t bytes ) { if( ptr ) pool_dealloc( ptr, bytes ); if( bytes <= MEMORY_POOL_MAX ) { int i; size_t index = LIST_INDEX( bytes ); size_t blk_count = BLOCK_COUNT( index ); mempage_t *erase = NULL, *prev = NULL, *curr = pool[index].first; if( pool_lock ) pool_lock( index ); while( curr ) { if( curr->count != blk_count ) /* 判断是否是空闲页 */ { prev = curr; curr = curr->next; } else { /* 从页面缓存中退出 */ for( i = 0; i < MEMORY_POOL_BUFFER; ++i ) { if( pool[index].buffer[i] == curr ) { pool[index].buffer[i] = NULL; break; } } if( prev ) prev->next = curr->next; /* 空闲页不在链首 */ else pool[index].first = curr->next; /* 空闲页在链首 */ /* 将空闲页释放 */ erase = curr; curr = curr->next; MEMFREE( erase ); --( pool[index].useable ); } /* end if */ } /* end while */ if( pool_unlock ) pool_unlock( index ); } }
static int pset_setattr(psetid_t pset, uint_t attr) { int error; if (secpolicy_pset(CRED()) != 0) return (set_errno(EPERM)); pool_lock(); if (pool_state == POOL_ENABLED) { pool_unlock(); return (set_errno(ENOTSUP)); } if (pset == PS_QUERY || PSET_BADATTR(attr)) { pool_unlock(); return (set_errno(EINVAL)); } if ((error = cpupart_setattr(pset, attr)) != 0) { pool_unlock(); return (set_errno(error)); } pool_unlock(); return (0); }
void mem_pool::pool_dealloc( void* ptr, size_t bytes ) { if( !ptr ) return; if( bytes <= MEMORY_POOL_MAX ) { size_t index = LIST_INDEX( bytes ); mempage_t *curr, *prev = NULL; unsigned char *begin, *end, *blk = (unsigned char*)ptr; if( pool_lock ) pool_lock( index ); curr = pool[index].first; while( curr ) { begin = (unsigned char*)curr + sizeof(mempage_t); end = begin + pool[index].page_size; if( blk < begin || blk >= end ) /* 判断ptr是否在当前页内 */ { prev = curr; curr = curr->next; } else { size_t blk_size = BLOCK_SIZE( index ); /* 检查ptr是否正确 */ if( (blk - begin) % blk_size == 0 ) { /* 将内存块回收至链表首部 */ memblk_t* pblk = (memblk_t*)ptr; pblk->next = curr->free; curr->free = pblk; /* 如果回收前内存页已满,则将可用页数加一 */ if( curr->count == 0 ) ++( pool[index].useable ); ++( curr->count ); /* 如果当前页不在链首,则将之移至链首 */ if( pool[index].first != curr ) { prev->next = curr->next; curr->next = pool[index].first; pool[index].first = curr; } ++pool_dealloc_count; } break; } /* end else */ } /* end while */ if( pool_unlock ) pool_unlock( index ); return; } /* end if */ /* ptr不是由内存池分配 */ MEMFREE( ptr ); ++pool_dealloc_count; }
static int pset_bind(psetid_t pset, idtype_t idtype, id_t id, psetid_t *opset) { kthread_t *tp; proc_t *pp; task_t *tk; kproject_t *kpj; contract_t *ct; zone_t *zptr; psetid_t oldpset; int error = 0; void *projbuf, *zonebuf; pool_lock(); if ((pset != PS_QUERY) && (pset != PS_SOFT) && (pset != PS_HARD) && (pset != PS_QUERY_TYPE)) { /* * Check if the set actually exists before checking * permissions. This is the historical error * precedence. Note that if pset was PS_MYID, the * cpupart_get_cpus call will change it to the * processor set id of the caller (or PS_NONE if the * caller is not bound to a processor set). */ if (pool_state == POOL_ENABLED) { pool_unlock(); return (set_errno(ENOTSUP)); } if (cpupart_get_cpus(&pset, NULL, NULL) != 0) { pool_unlock(); return (set_errno(EINVAL)); } else if (pset != PS_NONE && secpolicy_pset(CRED()) != 0) { pool_unlock(); return (set_errno(EPERM)); } } /* * Pre-allocate enough buffers for FSS for all active projects * and for all active zones on the system. Unused buffers will * be freed later by fss_freebuf(). */ mutex_enter(&cpu_lock); projbuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_PROJ); zonebuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_ZONE); switch (idtype) { case P_LWPID: pp = curproc; mutex_enter(&pidlock); mutex_enter(&pp->p_lock); if (id == P_MYID) { tp = curthread; } else { if ((tp = idtot(pp, id)) == NULL) { mutex_exit(&pp->p_lock); mutex_exit(&pidlock); error = ESRCH; break; } } error = pset_bind_thread(tp, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pp->p_lock); mutex_exit(&pidlock); break; case P_PID: mutex_enter(&pidlock); if (id == P_MYID) { pp = curproc; } else if ((pp = prfind(id)) == NULL) { mutex_exit(&pidlock); error = ESRCH; break; } error = pset_bind_process(pp, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); break; case P_TASKID: mutex_enter(&pidlock); if (id == P_MYID) id = curproc->p_task->tk_tkid; if ((tk = task_hold_by_id(id)) == NULL) { mutex_exit(&pidlock); error = ESRCH; break; } error = pset_bind_task(tk, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); task_rele(tk); break; case P_PROJID: pp = curproc; if (id == P_MYID) id = curprojid(); if ((kpj = project_hold_by_id(id, pp->p_zone, PROJECT_HOLD_FIND)) == NULL) { error = ESRCH; break; } mutex_enter(&pidlock); error = pset_bind_project(kpj, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); project_rele(kpj); break; case P_ZONEID: if (id == P_MYID) id = getzoneid(); if ((zptr = zone_find_by_id(id)) == NULL) { error = ESRCH; break; } mutex_enter(&pidlock); error = pset_bind_zone(zptr, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); zone_rele(zptr); break; case P_CTID: if (id == P_MYID) id = PRCTID(curproc); if ((ct = contract_type_ptr(process_type, id, curproc->p_zone->zone_uniqid)) == NULL) { error = ESRCH; break; } mutex_enter(&pidlock); error = pset_bind_contract(ct->ct_data, pset, &oldpset, projbuf, zonebuf); mutex_exit(&pidlock); contract_rele(ct); break; case P_PSETID: if (id == P_MYID || pset != PS_NONE || !INGLOBALZONE(curproc)) { error = EINVAL; break; } error = pset_unbind(id, projbuf, zonebuf, idtype); break; case P_ALL: if (id == P_MYID || pset != PS_NONE || !INGLOBALZONE(curproc)) { error = EINVAL; break; } error = pset_unbind(PS_NONE, projbuf, zonebuf, idtype); break; default: error = EINVAL; break; } fss_freebuf(projbuf, FSS_ALLOC_PROJ); fss_freebuf(zonebuf, FSS_ALLOC_ZONE); mutex_exit(&cpu_lock); pool_unlock(); if (error != 0) return (set_errno(error)); if (opset != NULL) { if (copyout(&oldpset, opset, sizeof (psetid_t)) != 0) return (set_errno(EFAULT)); } return (0); }
void* mem_pool::pool_alloc( size_t bytes ) { void* ptr = NULL; if( bytes > MEMORY_POOL_MAX ) { ptr = MEMALLOC( bytes ); } else { size_t index = LIST_INDEX( bytes ); if( pool_lock ) pool_lock( index ); if( pool[index].first && pool[index].useable > 0 ) { int i; mempage_t *prev = NULL, *curr = NULL; /* 先查找页面缓存 */ for( i = 0; i < MEMORY_POOL_BUFFER; ++i ) { if( pool[index].buffer[i] ) { ptr = pool[index].buffer[i]->free; pool[index].buffer[i]->free = pool[index].buffer[i]->free->next; --( pool[index].buffer[i]->count ); /* 如果该页已无空闲块,则将该页自页面缓存中退出 */ if( pool[index].buffer[i]->count == 0 ) { --( pool[index].useable ); pool[index].buffer[i] = NULL; } else { if( i > 0 ) { /* 如果该页不在缓存首,则将该页调整至缓存首 */ pool[index].buffer[0] = pool[index].buffer[i]; pool[index].buffer[i] = NULL; } } goto EXIT_POOL_ALLOC; } } /* end for */ /* 页面缓存为空,则遍历链中的所有内存页寻找空闲的内存块 */ curr = pool[index].first; while( curr ) { if( curr->count == 0 ) /* 该页中没有空闲块 */ { /* 进入下一页 */ prev = curr; curr = curr->next; } else /* 该页中有空闲块 */ { size_t page_count = 0; /* 统计遍历过的可用内存页 */ ptr = curr->free; curr->free = curr->free->next; --( curr->count ); if( curr->count == 0 ) --( pool[index].useable ); /* 继续遍历链表,寻找其他还有空闲块的页面,将之放入页面缓存 */ while( curr && page_count < pool[index].useable ) { if( curr->count != 0 ) { /* 页面缓存还有位置则放入页面缓存 */ if( page_count < MEMORY_POOL_BUFFER ) pool[index].buffer[page_count] = curr; ++page_count; /* 如果当前页未满并且不在链首,则将之移至链首 */ if( pool[index].first != curr ) { prev->next = curr->next; /* 保存下一页 */ curr->next = pool[index].first; pool[index].first = curr; curr = prev->next; /* 进入下一页 */ continue; } } /* 进入下一页 */ prev = curr; curr = curr->next; } goto EXIT_POOL_ALLOC; } /* end else */ } /* end while */ } /* end if pool[index].useable > 0 */ else { /* 该链下未分配内存页或无空闲块,此时需增加新的内存页 */ mempage_t* pg = NULL; size_t blk_size = BLOCK_SIZE( index ); /* 如果 page_size = 0,则计算该内存链下每个内存页需占用的字节数 */ if( 0 == pool[index].page_size ) { if( DEFAULT_PAGE_SIZE % blk_size == 0 ) pool[index].page_size = DEFAULT_PAGE_SIZE; else pool[index].page_size = (DEFAULT_PAGE_SIZE / blk_size) * blk_size; } pg = (mempage_t*)MEMALLOC( sizeof(mempage_t) + pool[index].page_size ); if( pg ) { memblk_t* curr = NULL; size_t i, blk_count = BLOCK_COUNT( index ); pg->next = pool[index].first; pool[index].first = pg; /* 将内存页中的所有内存块串联成一个链表 */ curr = (memblk_t*)((unsigned char*)pg + sizeof(mempage_t)); pg->free = curr; for( i = 1; i < blk_count; ++i ) { curr->next = (memblk_t*)((unsigned char*)curr + blk_size); curr = curr->next; } curr->next = NULL; ptr = pg->free; pg->free = pg->free->next; pg->count = blk_count - 1; ++( pool[index].useable ); pool[index].buffer[0] = pg; } } EXIT_POOL_ALLOC: if( pool_unlock ) pool_unlock( index ); } /* end else */ if( ptr ) ++pool_alloc_count; return ptr; }
void CServerSocket::DisconnectForReuse( CSocketBuffer * pBuffer ) { if( pBuffer == NULL ) return ; pool_lock() ; try{ if( pBuffer->m_bAccepted /*bAccepted*/ ) { COV_UNIT * pOV ; m_sendSlot.Get_SendUnit( &pOV, 1 ) ; pOV->SetOperation( mode_close_socket ) ; pBuffer->Shutdown( SD_BOTH ) ; //printf( "in DisconnetForReuse\n" ) ; if( pDisconnectEx ) { if( !DisconnectEx( pBuffer, static_cast<LPOVERLAPPED>(pOV), TF_REUSE_SOCKET ) ) { DWORD lastError = ::WSAGetLastError() ; if( ERROR_IO_PENDING != lastError ) { ::PrintConsole( "Error Disconnect : %d\n", lastError ) ; // 이건 어떻게 하나.. } } else { m_iocp.PostStatus( pBuffer->socket, 0, static_cast<LPOVERLAPPED>(pOV) ) ; } } else { if( !TransmitFile( pBuffer, static_cast<LPOVERLAPPED>(pOV) ) ) { DWORD lastError = ::WSAGetLastError() ; if( ERROR_IO_PENDING != lastError ) { ::PrintConsole( "Error Disconnect : %d\n", lastError ) ; // 이건 어떻게 하나.. } } else { m_iocp.PostStatus( pBuffer->socket, 0, static_cast<LPOVERLAPPED>(pOV) ) ; } } } else { } pBuffer->m_bAccepted = false ; } catch (...) { ::PrintConsole("[EXCEPTION] %s, %d \n", __FILE__, __LINE__ ) ; } pool_unlock() ; }
bool CServerSocket::AcceptCompleted( CSocketBuffer * pBuffer, DWORD dwReceiveByte ) { bool bRet ; // Accept 가 완료되면. if( pBuffer && pBuffer->IsConnected() ) { pool_lock() ; try{ pBuffer->m_bAccepted = true ; } catch (...) { ::PrintConsole("[exception] %s, %d \n", __FILE__, __LINE__ ) ; } pool_unlock() ; ::InterlockedDecrement( &m_nCurPendingAccept ) ; //SetEvent( m_hAcceptPostEvent ) ; int nEstablishedSeconds = 0; int bytes = sizeof(nEstablishedSeconds); int err = ::getsockopt(pBuffer->socket, SOL_SOCKET, SO_CONNECT_TIME, (char*)&nEstablishedSeconds, &bytes); if (nEstablishedSeconds == 0xffffffff) { // 현재 연결되지 않은 넘 ::PrintConsole( "[ERROR] Dissconnected socket \n") ; return false ; } else { // nEstablishedSeconds --> 커넥션 이루어진 때로부터 현재까지 경과한 초단위 시간 } if( SOCKET_ERROR == ::setsockopt( pBuffer->socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&m_listensocket, sizeof(m_listensocket) ) ) { ::PrintConsole( "CServerSocket::AcceptCompleted setsockopt failed - Code %d\n", ::WSAGetLastError() ) ; } // 주소를 채우고, // int sizeofLocal=0, sizeofRemote = 0 ; SOCKADDR * pLocal = NULL, * pRemote = NULL ; GetAcceptExSockaddrs( pBuffer->m_buf, 0, m_sizeofaddr, m_sizeofaddr, &pLocal, &sizeofLocal, &pRemote, &sizeofRemote ) ; if( pRemote ) { ::CopyMemory( &pBuffer->addr, pRemote, sizeof(SOCKADDR) ) ; //printf( "Ip = %s\n", inet_ntoa( pBuffer->addr.sin_addr ) ) ; } tcp_keepalive keepAlive, outKeepAlive = {0}; DWORD outByte ; keepAlive.onoff = 1 ; keepAlive.keepaliveinterval = _KEEPALIVE_INTERVAL_ ; keepAlive.keepalivetime = _KEEPALIVE_TIME_ ; WSAIoctl( pBuffer->socket, SIO_KEEPALIVE_VALS, &keepAlive, sizeof(keepAlive), &outKeepAlive, sizeof(outKeepAlive), &outByte, NULL, NULL ) ; // completion port 와 연결한다.. /* if( m_iocp.AssociateSocket( pBuffer ) == false ) { int iError = WSAGetLastError() ; ::PrintConsole( " m_iocp.AssociateSocket( pBuf ) == false (err_code :%d)\n", iError ) ; } */ //OnConnectionEstablished( pBuffer ) ; bRet = true ; } else { ::PrintConsole("[ERROR] if( pBuffer && pBuffer->IsConnected() == false ) \n" ) ; bRet = false ; } return bRet ; }
void CServerSocket::Accept() { CSocketBuffer * pBuffer = NULL ; pool_lock() ; try{ if( m_UsingPool.empty() == false ) { pBuffer = m_UsingPool.front() ; m_UsingPool.pop() ; } } catch (...) { ::PrintConsole("[exception] %s, %d \n", __FILE__, __LINE__ ) ; } pool_unlock() ; if( pBuffer ) { pBuffer->release() ; //pBuffer->InitSocket() ; pBuffer->SetMode( mode_accept_complete ) ; int nEstablishedSeconds = 0; int bytes = sizeof(nEstablishedSeconds); int err = ::getsockopt(pBuffer->socket, SOL_SOCKET, SO_CONNECT_TIME, (char*)&nEstablishedSeconds, &bytes); if (nEstablishedSeconds == 0xffffffff) { } else { // nEstablishedSeconds --> 커넥션 이루어진 때로부터 현재까지 경과한 초단위 시간 ::PrintConsole( "[ERROR] Already connected socket \n") ; pBuffer->Shutdown( SD_BOTH ) ; pool_lock() ; try{ pBuffer->release() ; m_UsingPool.push( pBuffer ) ; } catch (...) { printf("[exception] %s, %d \n", __FILE__, __LINE__ ) ; } pool_unlock() ; return ; } if( FALSE == AcceptEx( pBuffer ) ) { int err = WSAGetLastError() ; if( err != WSA_IO_PENDING ) { ::PrintConsole( "AcceptEx : Error %d\n", err ) ; return ; } } else { m_iocp.PostStatus( (DWORD)pBuffer, 0, static_cast<LPOVERLAPPED>(pBuffer) ) ; } ::InterlockedIncrement( &m_nCurPendingAccept ) ; } else { ::PrintConsole( "pop failed\n" ) ; } }
/*################################################################################# // // CServerSocket : 서버의 소켓 관리자. // //###############################################################################*/ BOOL CServerSocket::CreateServerSocket( int nWorker, char * listenip, u_short listenport, int nSendSlotCount, int nBufMegaSize, int nSockBufPool, int backlog /* = 10 */, int nAcceptPostMax /* = 20 */, int nAcceptPostMin /* = 10 */ ) { int i = 0 ; if( !InitializeCriticalSectionAndSpinCount( &m_csPool, 0x80000000 | 2000 ) ) { ::PrintConsole( "Critical Section Error\n" ) ; return FALSE ; } m_nMaxPendingAccept = nAcceptPostMax ; m_nMinPendingAccept = nAcceptPostMin ; m_nCurPendingAccept = 0 ; if( NULL == ( m_hAcceptPostEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) ) { ::PrintConsole( "Create Event Failed\n" ) ; return FALSE ; } if( NULL == ( m_hNoAcceptWaitEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) ) { ::PrintConsole( "Create Event Failed\n" ) ; return FALSE ; } if( NULL == ( m_hShutDownEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) ) { ::PrintConsole( "Create Event Failed\n" ) ; return FALSE ; } m_sizeofaddr = sizeof( SOCKADDR_IN ) + 16 ; m_listensocket = ::WSASocket( AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED ) ; if( m_listensocket == INVALID_SOCKET ) { ::PrintConsole( "WSASocket Error : Code %d\n", ::WSAGetLastError() ) ; return FALSE ; } m_addr.sin_port = htons( listenport ) ; m_addr.sin_addr.s_addr = inet_addr( listenip ) ; m_addr.sin_family = AF_INET ; if( SOCKET_ERROR == ::bind( m_listensocket, reinterpret_cast<struct sockaddr *>(&m_addr), sizeof(SOCKADDR_IN) ) ) { ::PrintConsole( "Bind Error : Code %d\n", ::WSAGetLastError() ) ; return FALSE ; } if( SOCKET_ERROR == ::listen( m_listensocket, 10 ) ) { ::PrintConsole( "Listen Error : Code %d\n", ::WSAGetLastError() ) ; return FALSE ; } if( !LoadExtensionFunctions() ) { return FALSE ; } if( false == m_sendSlot.CreateOVSlot( nSendSlotCount, nBufMegaSize ) ) { ::PrintConsole( "SendSlot Create Failed\n" ) ; return FALSE ; } // 리슨 소켓을 iocp 에 묶는다. if( !m_iocp.Create( nWorker ) ) { return FALSE ; } m_nMaxPoolCount = nSockBufPool ; CSocketBuffer * pBuf = NULL ; for( i = 0 ; i < nSockBufPool ; i++ ) { pBuf = new CSocketBuffer(this) ; if( pBuf ){ if( pBuf->InitSocket() ) { if( m_iocp.AssociateSocket( pBuf ) ) { pool_lock() ; m_UsingPool.push( pBuf ) ; pool_unlock() ; } else { int iError = WSAGetLastError() ; ::PrintConsole( " m_iocp.AssociateSocket( pBuf ) == false (err_code :%d)\n", iError ) ; return FALSE ; } } else { ::PrintConsole( " init socket error \n" ) ; return FALSE ; } } else return FALSE ; } if( !m_iocp.AssociateSocket( m_listensocket ) ) { return FALSE ; } m_hAcceptPostEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ; if( !m_hAcceptPostEvent ) { return FALSE ; } unsigned int threadid ; HANDLE handle ; m_nWorkerThread = nWorker ; for( i = 0 ; i < nWorker ; i++ ) { handle = (HANDLE)::_beginthreadex( 0, 0, WorkerThread, (void*)this, 0, &threadid ) ; if( handle == INVALID_HANDLE_VALUE ) { return FALSE ; } } // 자체 스레드 시작. Start() ; return TRUE ; }