fr_talloc_link_ctx(ctx, ef);
+ ef->max_entries = max_entries;
+ ef->max_idle = max_idle;
+ ef->locking = locking;
+
+ /*
+ * If we're not locking the files, just return the
+ * handle. Each call to exfile_open() will just open a
+ * new file descriptor.
+ */
+ if (!ef->locking) return ef;
+
ef->entries = talloc_zero_array(ef, exfile_entry_t, max_entries);
if (!ef->entries) {
talloc_free(ef);
return NULL;
}
- ef->max_entries = max_entries;
- ef->max_idle = max_idle;
- ef->locking = locking;
-
talloc_set_destructor(ef, _exfile_free);
return ef;
int i, tries, unused = -1, found = -1, oldest = -1;
bool do_cleanup = false;
uint32_t hash;
- time_t now = time(NULL);
+ time_t now;
struct stat st;
if (!ef || !filename) return -1;
+ /*
+ * No locking: just return a new FD.
+ */
+ if (!ef->locking) {
+ found = exfile_open_mkdir(ef, filename, permissions);
+ if (found < 0) return -1;
+
+ (void) lseek(found, 0, SEEK_END);
+ return found;
+ }
+
+ /*
+ * It's faster to do hash comparisons of a string than
+ * full string comparisons.
+ */
hash = fr_hash_string(filename);
+ now = time(NULL);
unused = -1;
pthread_mutex_lock(&ef->mutex);
found = i;
/*
- * If we're not cleanin up, stop now.
+ * If we're not cleaning up, stop now.
*/
if (!do_cleanup) break;
/*
- * If we are cleaning up, and only
+ * If we are cleaning up, then clean up
* entries OTHER than the one we found,
* do so now.
*/
*/
if (found >= 0) {
i = found;
- goto do_return;
+ goto try_lock;
}
/*
exfile_trigger_exec(ef, request, &ef->entries[i], "open");
-do_return:
+try_lock:
/*
* Lock from the start of the file.
*/
error:
exfile_cleanup_entry(ef, request, &ef->entries[i]);
-
pthread_mutex_unlock(&(ef->mutex));
return -1;
}
{
uint32_t i;
- for (i = 0; i < ef->max_entries; i++) {
- if (!ef->entries[i].filename) continue;
-
- /*
- * Unlock the bytes that we had previously locked.
- */
- if (ef->entries[i].fd == fd) {
- if (ef->locking) (void) rad_unlockfd(ef->entries[i].fd, 0);
+ /*
+ * No locking: just close the file.
+ */
+ if (!ef->locking) {
+ close(fd);
+ return 0;
+ }
- pthread_mutex_unlock(&(ef->mutex));
+ /*
+ * Unlock the bytes that we had previously locked.
+ */
+ for (i = 0; i < ef->max_entries; i++) {
+ if (ef->entries[i].fd != fd) continue;
- exfile_trigger_exec(ef, request, &ef->entries[i], "release");
+ (void) lseek(ef->entries[i].fd, 0, SEEK_SET);
+ (void) rad_unlockfd(ef->entries[i].fd, 0);
+ pthread_mutex_unlock(&(ef->mutex));
- return 0;
- }
+ exfile_trigger_exec(ef, request, &ef->entries[i], "release");
+ return 0;
}
pthread_mutex_unlock(&(ef->mutex));