예제 #1
0
파일: ketama.c 프로젝트: wayfair/ketama
/** \brief Locks the semaphore only after it is unlocked by another process.
  * \param sem_set_id The semaphore handle that you want to lock. */
static void
ketama_sem_safely_lock( int sem_set_id )
{
    int sanity = 0;
    while ( semctl( sem_set_id, 0, GETVAL, 0 ) == 2 )
    {
        // wait for the continuum creator to finish, but don't block others
        usleep( 5 );

        // if we are waiting for > 1 second, take drastic action:
        if(++sanity > 200000)
        {
            usleep( rand()%50000 );
            ketama_sem_unlock( sem_set_id );
            break;
        }
    }

    ketama_sem_lock( sem_set_id );
}
예제 #2
0
파일: ketama.c 프로젝트: lsm/zir
int
ketama_roll( ketama_continuum* contptr, char* filename )
{
    strcpy( k_error, "" );

    key_t key;
    int shmid;
    int *data;
    int sem_set_id;

//     setlogmask( LOG_UPTO ( LOG_NOTICE | LOG_ERR | LOG_INFO ) );
//     openlog( "ketama", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1 );

    key = ftok( filename, 'R' );
    if ( key == -1 )
    {
        sprintf( k_error, "Invalid filename specified: %s", filename );
        return 0;
    }

    *contptr = malloc( sizeof( continuum ) );
    (*contptr)->numpoints = 0;
    (*contptr)->array = 0;
    (*contptr)->modtime = 0;

    sem_set_id = ketama_sem_init( key );

    int sanity = 0;
    while ( semctl( sem_set_id, 0, GETVAL, 0 ) == 2 )
    {
        // wait for the continuum creator to finish, but don't block others
        usleep( 5 );

        // if we are waiting for > 1 second, take drastic action:
        if(++sanity > 1000000)
	{
            usleep( rand()%50000 );
            ketama_sem_unlock( sem_set_id );
	    break;
        }
    }

    time_t modtime = file_modtime( filename );
    time_t* fmodtime = 0;
    while ( !fmodtime || modtime != *fmodtime )
    {
        shmid = shmget( key, MC_SHMSIZE, 0 ); // read only attempt.
        data = shmat( shmid, (void *)0, SHM_RDONLY );

        if ( data == (void *)(-1) || (*contptr)->modtime != 0 )
        {
            ketama_sem_lock( sem_set_id );

//          if ( (*contptr)->modtime == 0 )
//              syslog( LOG_INFO, "Shared memory empty, creating and populating...\n" );
//          else
//              syslog( LOG_INFO, "Server definitions changed, reloading...\n" );

            if ( !ketama_create_continuum( key, filename ) )
            {
//                 strcpy( k_error, "Ketama_create_continuum() failed!" );
                ketama_sem_unlock( sem_set_id );
                return 0;
            }
/*          else
                syslog( LOG_INFO, "ketama_create_continuum() successfully finished.\n" );*/
    
            shmid = shmget( key, MC_SHMSIZE, 0 ); // read only attempt.
            data = shmat( shmid, (void *)0, SHM_RDONLY );
            ketama_sem_unlock( sem_set_id );
        }
    
        if ( data == (void *)(-1) )
        {
            strcpy( k_error, "Failed miserably to get pointer to shmemdata!" );
            return 0;
        }

        (*contptr)->numpoints = *data;
        (*contptr)->modtime = ++data;
        (*contptr)->array = data + sizeof( void* );
        fmodtime = (time_t*)( (*contptr)->modtime );
    }

    return 1;
}