static void fab_close(fa_handle_t *handle) { #ifdef FILE_PARKING buffered_file_t *closeme = NULL, *bf = (buffered_file_t *)handle; if(bf->bf_src->fh_proto->fap_flags & FAP_NO_PARKING) { fab_destroy((buffered_file_t *)handle); return; } hts_mutex_lock(&buffered_global_mutex); if(parked) closeme = parked; parked = bf; time(&parked->bf_park_time); hts_mutex_unlock(&buffered_global_mutex); if(closeme) fab_destroy(closeme); #else fab_destroy((buffered_file_t *)handle); #endif }
fa_handle_t * fa_buffered_open(const char *url, char *errbuf, size_t errsize, int flags, struct fa_open_extra *foe) { buffered_file_t *closeme = NULL; fa_handle_t *fh = NULL; hts_mutex_lock(&buffered_global_mutex); if(parked) { // Flush too old parked files time_t now; time(&now); if(now - parked->bf_park_time > 10) { closeme = parked; parked = NULL; } } if(parked && !strcmp(parked->bf_url, url)) { parked->bf_fpos = 0; fh = (fa_handle_t *)parked; parked = NULL; } hts_mutex_unlock(&buffered_global_mutex); if(closeme != NULL) fab_destroy(closeme); if(fh != NULL) return fh; int mflags = flags; flags &= ~ (FA_BUFFERED_SMALL | FA_BUFFERED_BIG | FA_BUFFERED_NO_PREFETCH); fh = fa_open_ex(url, errbuf, errsize, flags, foe); if(fh == NULL) return NULL; if(!(fh->fh_proto->fap_flags & FAP_ALLOW_CACHE)) return fh; buffered_file_t *bf = calloc(1, sizeof(buffered_file_t)); bf->bf_url = strdup(url); if(!(mflags & FA_BUFFERED_NO_PREFETCH)) bf->bf_min_request = mflags & FA_BUFFERED_BIG ? 256 * 1024 : 64 * 1024; bf->bf_mem_size = 1024 * 1024; bf->bf_flags = flags; bf->bf_src = fh; bf->bf_size = -1; bf->h.fh_proto = &fa_protocol_buffered; #if BF_CHK bf->bf_chk = fa_open_ex(url, NULL, 0, 0, NULL); #endif return &bf->h; }