mapcache_lock_result mapcache_locker_disk_aquire_lock(mapcache_context *ctx, mapcache_locker *self, char *resource, void **lock) { char *lockname, errmsg[120]; mapcache_locker_disk *ldisk; apr_file_t *lockfile; apr_status_t rv; assert(self->type == MAPCACHE_LOCKER_DISK); ldisk = (mapcache_locker_disk*)self; *lock = NULL; /*unused*/ lockname = lock_filename_for_resource(ctx,ldisk,resource); /* create the lockfile */ rv = apr_file_open(&lockfile,lockname,APR_WRITE|APR_CREATE|APR_EXCL|APR_XTHREAD,APR_OS_DEFAULT,ctx->pool); /* if the file already exists, wait for it to disappear */ /* TODO: check the lock isn't stale (i.e. too old) */ if( rv != APR_SUCCESS ) { if( !APR_STATUS_IS_EEXIST(rv) ) { ctx->set_error(ctx, 500, "failed to create lockfile %s: %s", lockname, apr_strerror(rv,errmsg,120)); return MAPCACHE_LOCK_NOENT; } return MAPCACHE_LOCK_LOCKED; } else { /* we acquired the lock */ char *pid_s; pid_t pid; apr_size_t pid_s_len; pid = getpid(); pid_s = apr_psprintf(ctx->pool,"%"APR_PID_T_FMT,pid); pid_s_len = strlen(pid_s); apr_file_write(lockfile,pid_s,&pid_s_len); apr_file_close(lockfile); return MAPCACHE_LOCK_AQUIRED; } }
int mapcache_lock_or_wait_for_resource(mapcache_context *ctx, char *resource) { char *lockname = lock_filename_for_resource(ctx,resource); apr_file_t *lockfile; apr_status_t rv; /* create the lockfile */ rv = apr_file_open(&lockfile,lockname,APR_WRITE|APR_CREATE|APR_EXCL|APR_XTHREAD,APR_OS_DEFAULT,ctx->pool); /* if the file already exists, wait for it to disappear */ /* TODO: check the lock isn't stale (i.e. too old) */ if( rv != APR_SUCCESS ) { apr_finfo_t info; rv = apr_stat(&info,lockname,0,ctx->pool); #ifdef DEBUG if(!APR_STATUS_IS_ENOENT(rv)) { ctx->log(ctx, MAPCACHE_DEBUG, "waiting on resource lock %s", resource); } #endif while(!APR_STATUS_IS_ENOENT(rv)) { /* sleep for the configured number of micro-seconds (default is 1/100th of a second) */ apr_sleep(ctx->config->lock_retry_interval); rv = apr_stat(&info,lockname,0,ctx->pool); } return MAPCACHE_FALSE; } else { /* we acquired the lock */ apr_file_close(lockfile); return MAPCACHE_TRUE; } }
mapcache_lock_result mapcache_locker_disk_ping_lock(mapcache_context *ctx, mapcache_locker *self, char *resource, void *lock) { apr_finfo_t info; apr_status_t rv; char *lockname; mapcache_locker_disk *ldisk = (mapcache_locker_disk*)self; lockname = lock_filename_for_resource(ctx,ldisk,resource); rv = apr_stat(&info,lockname,0,ctx->pool); if(APR_STATUS_IS_ENOENT(rv)) { return MAPCACHE_LOCK_NOENT; } else { return MAPCACHE_LOCK_LOCKED; } }
void mapcache_locker_disk_release_lock(mapcache_context *ctx, mapcache_locker *self, char *resource, void *lock) { mapcache_locker_disk *ld = (mapcache_locker_disk*)self; char *lockname = lock_filename_for_resource(ctx,ld,resource); apr_file_remove(lockname,ctx->pool); }
void mapcache_unlock_resource(mapcache_context *ctx, char *resource) { char *lockname = lock_filename_for_resource(ctx,resource); apr_file_remove(lockname,ctx->pool); }