Пример #1
0
bool CLock::timed_lock(uint32_t millisecond)
{
	int retval;

	if (0 == millisecond)
	{
		retval = pthread_mutex_lock(&_mutex);
	}
	else
	{	
		struct timespec abstime;

#if _POSIX_C_SOURCE >= 199309L
		clock_gettime(CLOCK_REALTIME, &abstime);    
		abstime.tv_sec  += millisecond / 1000;
		abstime.tv_nsec += (millisecond % 1000) * 1000000;
#else
#endif // _POSIX_C_SOURCE
        struct timeval tv;
        if (-1 == gettimeofday(&tv, NULL))
            throw CSyscallException(errno, __FILE__, __LINE__);

        abstime.tv_sec = tv.tv_sec;
        abstime.tv_nsec = tv.tv_usec * 1000;
        abstime.tv_sec  += millisecond / 1000;
        abstime.tv_nsec += (millisecond % 1000) * 1000000;
        
		retval = pthread_mutex_timedlock(&_mutex, &abstime);
	}
	
	if (0 == retval) return true;
    if (ETIMEDOUT == retval) return false;
	
    throw CSyscallException(retval, __FILE__, __LINE__);
}
Пример #2
0
SYS_NAMESPACE_BEGIN

CLock::CLock(bool recursive)
{
    int retval = 0;
    if (recursive)
    {    
#if defined(__linux) && !defined(__USE_UNIX98)        
        const pthread_mutexattr_t attr = { PTHREAD_MUTEX_RECURSIVE_NP };
#else
        retval = pthread_mutexattr_init(&_attr);
        if (retval != 0) {
            throw CSyscallException(retval, __FILE__, __LINE__);
        }
        
        pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE);
        if (retval != 0) {
            pthread_mutexattr_destroy(&_attr);        
            throw CSyscallException(retval, __FILE__, __LINE__);
        }
#endif    
        retval = pthread_mutex_init(&_mutex, &_attr);
    }
    else {
        retval = pthread_mutex_init(&_mutex, NULL);
    }
    
    if (retval != 0) {
        pthread_mutexattr_destroy(&_attr);    
        throw CSyscallException(retval, __FILE__, __LINE__);
    }
}
Пример #3
0
void CMMap::async_flush(mmap_t* ptr, size_t offset, size_t length, bool invalid)
{
    // 无效参数
    if (offset >= ptr->len)
        throw CSyscallException(EINVAL, __FILE__, __LINE__);
    
    int flags = invalid? MS_ASYNC|MS_INVALIDATE: MS_ASYNC;
    if (-1 == msync(((char*)(ptr->addr))+offset, (offset+length > ptr->len)? ptr->len-offset: length, flags))
        throw CSyscallException(errno, __FILE__, __LINE__);
}
Пример #4
0
mmap_t* CMMap::map_both(const char* filename, size_t size_max)
{
    int fd = open(filename, O_RDONLY|O_WRONLY);
    if (-1 == fd)
        throw CSyscallException(errno, __FILE__, __LINE__);
    
    return do_map(PROT_READ|PROT_WRITE, fd, 0, 0, size_max, false);
}
Пример #5
0
bool CLock::try_lock()
{
    int retval = pthread_mutex_trylock(&_mutex);

    if (0 == retval) return true;
	if (EBUSY == retval) return false;

    throw CSyscallException(retval, __FILE__, __LINE__);
}
Пример #6
0
SYS_NAMESPACE_BEGIN

mmap_t* CMMap::map_read(const char* filename, size_t size_max)
{
    int fd = open(filename, O_RDONLY);
    if (-1 == fd)
        throw CSyscallException(errno, __FILE__, __LINE__);
    
    return do_map(PROT_READ, fd, 0, 0, size_max, false);
}
Пример #7
0
mmap_t* CMMap::do_map(int prot, int fd, size_t size, size_t offset, size_t size_max, bool byfd)
{
	mmap_t* ptr = new mmap_t;

    try
    {        
        struct stat st;
        if (-1 == fstat(fd, &st))
            throw CSyscallException(errno, __FILE__, __LINE__);
		
        ptr->fd = byfd? -fd: fd;
        ptr->len = (0 == size)? ((size_t)st.st_size-offset): (size+offset > (size_t)st.st_size)? (size_t)st.st_size: (size+offset);
		ptr->addr = NULL;

		if ((0 == size_max) || (ptr->len < size_max))
		{
			void* addr = mmap(NULL, ptr->len, prot, MAP_SHARED, fd, offset);
			if (MAP_FAILED == addr)
				throw CSyscallException(errno, __FILE__, __LINE__);

			ptr->addr = addr;
		}        
        
        return ptr;
    }
    catch (CSyscallException& ex)
    {
        // 谁打开谁关闭
        if (ptr->fd > -1)
        {
            close(ptr->fd);
            ptr->fd = -1;
        }
        
		delete ptr;
        throw;
    }    
}
Пример #8
0
void CMMap::unmap(mmap_t* ptr)
{
	if (ptr->addr != NULL)
    {
		if (-1 == munmap(ptr->addr, ptr->len))
		   throw CSyscallException(errno, __FILE__, __LINE__);
	}

    // 谁打开谁关闭
    if (ptr->fd > -1) 
    {
        close(ptr->fd);
        ptr->fd = -1;
    }
    
    delete ptr;
}
Пример #9
0
void CLock::unlock()
{
    int retval = pthread_mutex_unlock(&_mutex);
    if (retval != 0)
        throw CSyscallException(retval, __FILE__, __LINE__);
}