static int blobcache_save(int fd, const void *data, size_t size, time_t expire, int lockhash) { uint8_t buf[4]; #ifndef BC_USE_FILE_LOCKS hts_mutex_lock(&blobcache_lock[lockhash & BC_FILE_LOCKS_MASK]); #else if(flock(fd, LOCK_EX)) return -1; #endif buf[0] = expire >> 24; buf[1] = expire >> 16; buf[2] = expire >> 8; buf[3] = expire; if(write(fd, buf, 4) != 4) goto bad; if(write(fd, data, size) != size) goto bad; if(ftruncate(fd, size + 4)) goto bad; hts_mutex_lock(&blobcache_mutex); blobcache_size_current += size + 4; if(blobcache_size_current > blobcache_size_max) { if(!callout_isarmed(&blobcache_callout)) callout_arm(&blobcache_callout, blobcache_do_prune, NULL, 5); } hts_mutex_unlock(&blobcache_mutex); #ifndef BC_USE_FILE_LOCKS hts_mutex_unlock(&blobcache_lock[lockhash & BC_FILE_LOCKS_MASK]); #endif return 0; bad: #ifndef BC_USE_FILE_LOCKS hts_mutex_unlock(&blobcache_lock[lockhash & BC_FILE_LOCKS_MASK]); #endif return -1; }
static void blobcache_put0(sqlite3 *db, const char *key, const char *stash, const void *data, size_t size, int maxage, const char *etag, time_t mtime) { int rc; time_t now = time(NULL); sqlite3_stmt *stmt; rc = sqlite3_prepare_v2(db, "INSERT OR REPLACE INTO item " "(k, stash, payload, lastaccess, expiry, etag, modtime) " "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)", -1, &stmt, NULL); if(rc != SQLITE_OK) { TRACE(TRACE_ERROR, "SQLITE", "SQL Error at %s:%d", __FUNCTION__, __LINE__); return; } sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, stash, -1, SQLITE_STATIC); sqlite3_bind_blob(stmt, 3, data, size, SQLITE_STATIC); sqlite3_bind_int(stmt, 4, now); sqlite3_bind_int64(stmt, 5, (int64_t)now + maxage); if(etag != NULL) sqlite3_bind_text(stmt, 6, etag, -1, SQLITE_STATIC); if(mtime != 0) sqlite3_bind_int(stmt, 7, mtime); rc = sqlite3_step(stmt); sqlite3_finalize(stmt); int s = atomic_add(&estimated_cache_size, size) + size; if(blobcache_compute_maxsize(s) < s && !callout_isarmed(&blobcache_callout)) callout_arm(&blobcache_callout, blobcache_do_prune, NULL, 5); }