Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/*
 * 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;
	}
}
Ejemplo n.º 3
0
/*
 * 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;
}
Ejemplo n.º 4
0
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 );
    }
}
Ejemplo n.º 5
0
Archivo: smalloc.c Proyecto: Rapaka/fio
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);
}
Ejemplo n.º 6
0
/*
 * 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);
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
Archivo: smalloc.c Proyecto: Rapaka/fio
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;
}
Ejemplo n.º 9
0
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);
    }
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
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 );
    }
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
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() ;
	
}
Ejemplo n.º 17
0
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 ;
}
Ejemplo n.º 18
0
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" ) ;
	}
}
Ejemplo n.º 19
0
/*#################################################################################
//
//  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 ;
}