* Remove the cache lock, if present. * * First, try to close the file handle, whose delete-on-close should * kill the file. Otherwise, just delete the file by name. * * If no lock name has yet been calculated, do the calculation of the * lock name first before trying to delete the file. * * If an optional bucket brigade is passed, the lock will only be * removed if the bucket brigade cont
| 388 | * removed if the bucket brigade contains an EOS bucket. |
| 389 | */ |
| 390 | apr_status_t cache_remove_lock(cache_server_conf *conf, |
| 391 | cache_request_rec *cache, request_rec *r, apr_bucket_brigade *bb) |
| 392 | { |
| 393 | void *dummy; |
| 394 | const char *lockname; |
| 395 | |
| 396 | if (!conf || !conf->lock || !conf->lockpath) { |
| 397 | /* no locks configured, leave */ |
| 398 | return APR_SUCCESS; |
| 399 | } |
| 400 | if (bb) { |
| 401 | apr_bucket *e; |
| 402 | int eos_found = 0; |
| 403 | for (e = APR_BRIGADE_FIRST(bb); |
| 404 | e != APR_BRIGADE_SENTINEL(bb); |
| 405 | e = APR_BUCKET_NEXT(e)) |
| 406 | { |
| 407 | if (APR_BUCKET_IS_EOS(e)) { |
| 408 | eos_found = 1; |
| 409 | break; |
| 410 | } |
| 411 | } |
| 412 | if (!eos_found) { |
| 413 | /* no eos found in brigade, don't delete anything just yet, |
| 414 | * we are not done. |
| 415 | */ |
| 416 | return APR_SUCCESS; |
| 417 | } |
| 418 | } |
| 419 | apr_pool_userdata_get(&dummy, CACHE_LOCKFILE_KEY, r->pool); |
| 420 | if (dummy) { |
| 421 | return apr_file_close((apr_file_t *)dummy); |
| 422 | } |
| 423 | apr_pool_userdata_get(&dummy, CACHE_LOCKNAME_KEY, r->pool); |
| 424 | lockname = (const char *)dummy; |
| 425 | if (!lockname) { |
| 426 | char dir[5]; |
| 427 | |
| 428 | /* create the key if it doesn't exist */ |
| 429 | if (!cache->key) { |
| 430 | cache_generate_key(r, r->pool, &cache->key); |
| 431 | } |
| 432 | |
| 433 | /* create a hashed filename from the key, and save it for later */ |
| 434 | lockname = ap_cache_generate_name(r->pool, 0, 0, cache->key); |
| 435 | |
| 436 | /* lock files represent discrete just-went-stale URLs "in flight", so |
| 437 | * we support a simple two level directory structure, more is overkill. |
| 438 | */ |
| 439 | dir[0] = '/'; |
| 440 | dir[1] = lockname[0]; |
| 441 | dir[2] = '/'; |
| 442 | dir[3] = lockname[1]; |
| 443 | dir[4] = 0; |
| 444 | |
| 445 | lockname = apr_pstrcat(r->pool, conf->lockpath, dir, "/", lockname, NULL); |
| 446 | } |
| 447 | return apr_file_remove(lockname, r->pool); |
no test coverage detected