summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-05-14 02:24:44 +0000
committerCarl Hetherington <carl@carlh.net>2010-05-14 02:24:44 +0000
commit0fd0679c67bdac2b6fb8aa7a9b5cca7592baa7ab (patch)
tree0e1645688a95e03d76d3a6469865418bbc9ebef0 /libs/ardour/ardour
parent1f196b40138d779d87a02d2f10e0cefe9a454fd1 (diff)
Keep to a quota of open files by closing least recently used ones as required. Should fix #2341.
git-svn-id: svn://localhost/ardour2/branches/3.0@7101 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r--libs/ardour/ardour/audiosource.h4
-rw-r--r--libs/ardour/ardour/debug.h1
-rw-r--r--libs/ardour/ardour/file_manager.h128
-rw-r--r--libs/ardour/ardour/sndfilesource.h5
4 files changed, 136 insertions, 2 deletions
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index c4a6e4e475..9879c75a8d 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -32,6 +32,7 @@
#include "ardour/source.h"
#include "ardour/ardour.h"
#include "ardour/readable.h"
+#include "ardour/file_manager.h"
#include "pbd/stateful.h"
#include "pbd/xml++.h"
@@ -140,7 +141,8 @@ class AudioSource : virtual public Source,
framecnt_t frames_per_peak);
private:
- int peakfile;
+ FdFileDescriptor* _peakfile_descriptor;
+ int _peakfile_fd;
framecnt_t peak_leftover_cnt;
framecnt_t peak_leftover_size;
Sample* peak_leftovers;
diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h
index 57b66a8793..33d973389a 100644
--- a/libs/ardour/ardour/debug.h
+++ b/libs/ardour/ardour/debug.h
@@ -46,6 +46,7 @@ namespace PBD {
extern uint64_t MidiClock;
extern uint64_t Monitor;
extern uint64_t Solo;
+ extern uint64_t FileManager;
}
}
diff --git a/libs/ardour/ardour/file_manager.h b/libs/ardour/ardour/file_manager.h
new file mode 100644
index 0000000000..86eb9676fa
--- /dev/null
+++ b/libs/ardour/ardour/file_manager.h
@@ -0,0 +1,128 @@
+/*
+ Copyright (C) 2010 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __file_manager_h__
+#define __file_manager_h__
+
+#include <sys/types.h>
+#include <string>
+#include <map>
+#include <sndfile.h>
+#include <glibmm/thread.h>
+#include "pbd/signals.h"
+
+namespace ARDOUR {
+
+class FileManager;
+
+/** Parent class for FileDescriptors.
+ *
+ * When a subclass is instantiated, the file it describes is added to a
+ * list. The FileDescriptor can be `allocated', meaning that its
+ * file will be opened on the filesystem, and can then be `released'.
+ * FileDescriptors are reference counted as they are allocated and
+ * released. When a descriptor's refcount is 0, the file on the
+ * filesystem is eligible to be closed if necessary to free up file
+ * handles for other files.
+ *
+ * The upshot of all this is that Ardour can manage the number of
+ * open files to stay within limits imposed by the operating system.
+ */
+
+class FileDescriptor
+{
+public:
+ FileDescriptor (std::string const &, bool);
+ virtual ~FileDescriptor () {}
+
+ void release ();
+
+ /** Emitted when the file is closed */
+ PBD::Signal0<void> Closed;
+
+protected:
+
+ friend class FileManager;
+
+ /* These methods and variables must be called / accessed
+ with a lock held on the FileManager's mutex
+ */
+
+ /** @return false on success, true on failure */
+ virtual bool open () = 0;
+ virtual void close () = 0;
+ virtual bool is_open () const = 0;
+
+ int refcount; ///< number of active users of this file
+ double last_used; ///< monotonic time that this file was last allocated
+ std::string name; ///< filename
+ bool writeable; ///< true if it should be opened writeable, otherwise false
+
+ FileManager* manager ();
+
+private:
+
+ static FileManager* _manager;
+};
+
+/** FileDescriptor for a file to be opened using libsndfile */
+class SndFileDescriptor : public FileDescriptor
+{
+public:
+ SndFileDescriptor (std::string const &, bool, SF_INFO *);
+ ~SndFileDescriptor ();
+
+ SNDFILE* allocate ();
+
+private:
+
+ friend class FileManager;
+
+ bool open ();
+ void close ();
+ bool is_open () const;
+
+ SNDFILE* _sndfile; ///< SNDFILE* pointer, or 0 if the file is closed
+ SF_INFO* _info; ///< libsndfile's info for this file
+};
+
+/** FileDescriptor for a file to be opened using POSIX open */
+class FdFileDescriptor : public FileDescriptor
+{
+public:
+ FdFileDescriptor (std::string const &, bool, mode_t);
+ ~FdFileDescriptor ();
+
+ int allocate ();
+
+private:
+
+ friend class FileManager;
+
+ bool open ();
+ void close ();
+ bool is_open () const;
+
+ int _fd; ///< file descriptor, or -1 if the file is closed
+ mode_t _mode; ///< mode to use when creating files
+};
+
+}
+
+#endif
diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h
index 96f39de2c8..2338e35bb0 100644
--- a/libs/ardour/ardour/sndfilesource.h
+++ b/libs/ardour/ardour/sndfilesource.h
@@ -24,6 +24,7 @@
#include "ardour/audiofilesource.h"
#include "ardour/broadcast_info.h"
+#include "ardour/file_manager.h"
namespace ARDOUR {
@@ -72,13 +73,14 @@ class SndFileSource : public AudioFileSource {
framecnt_t write_float (Sample* data, framepos_t pos, framecnt_t cnt);
private:
- SNDFILE *sf;
+ SndFileDescriptor* _descriptor;
SF_INFO _info;
BroadcastInfo *_broadcast_info;
void init_sndfile ();
int open();
int setup_broadcast_info (framepos_t when, struct tm&, time_t);
+ void file_closed ();
/* destructive */
@@ -100,6 +102,7 @@ class SndFileSource : public AudioFileSource {
framecnt_t nondestructive_write_unlocked (Sample *dst, framecnt_t cnt);
void handle_header_position_change ();
PBD::ScopedConnection header_position_connection;
+ PBD::ScopedConnection file_manager_connection;
};
} // namespace ARDOUR