Correct a typo in 'msvc_pbd.h'
[ardour.git] / libs / pbd / file_manager.cc
index 25d171b9590c92373995b6ab858204a10022c138..2cfa63ae39c19aa387b12e79fbbfb550fcad7a61 100644 (file)
 */
 
 #include <sys/time.h>
-#include <sys/resource.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <cassert>
-#include <iostream>
+#include <cstdio>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#ifdef __APPLE__
+#include <mach/mach_time.h>
+#endif
+
 #include "pbd/compose.h"
 #include "pbd/file_manager.h"
+#include "pbd/resource.h"
 #include "pbd/debug.h"
 
 using namespace std;
@@ -33,41 +41,14 @@ using namespace PBD;
 
 FileManager* FileDescriptor::_manager;
 
-namespace PBD {
-
-/** Class to limit the number of files held open */
-class FileManager
-{
-public:
-       FileManager ();
-       
-       void add (FileDescriptor *);
-       void remove (FileDescriptor *);
-
-       void release (FileDescriptor *);
-       bool allocate (FileDescriptor *);
-
-private:
-       
-       void close (FileDescriptor *);
-
-       std::list<FileDescriptor*> _files; ///< files we know about
-       Glib::Mutex _mutex; ///< mutex for _files, _open and FileDescriptor contents
-       int _open; ///< number of open files
-       int _max_open; ///< maximum number of open files
-};
-
-}
-
 FileManager::FileManager ()
        : _open (0)
 {
-       struct rlimit rl;
-       int const r = getrlimit (RLIMIT_NOFILE, &rl);
+       struct ResourceLimit rl;
        
        /* XXX: this is a bit arbitrary */
-       if (r == 0) {
-               _max_open = rl.rlim_cur - 64;
+       if (get_resource_limit (OpenFiles, rl)) {
+               _max_open = rl.current_limit - 64;
        } else {
                _max_open = 256;
        }
@@ -78,7 +59,7 @@ FileManager::FileManager ()
 void
 FileManager::add (FileDescriptor* d)
 {
-       Glib::Mutex::Lock lm (_mutex);
+       Glib::Threads::Mutex::Lock lm (_mutex);
        _files.push_back (d);
 }
 
@@ -86,7 +67,7 @@ FileManager::add (FileDescriptor* d)
 bool
 FileManager::allocate (FileDescriptor* d)
 {
-       Glib::Mutex::Lock lm (_mutex);
+       Glib::Threads::Mutex::Lock lm (_mutex);
 
        if (!d->is_open()) {
                
@@ -120,24 +101,32 @@ FileManager::allocate (FileDescriptor* d)
                                DEBUG::FileManager,
                                string_compose (
                                        "closed file for %1 to release file handle; now have %2 of %3 open\n",
-                                       (*oldest)->_name, _open, _max_open
+                                       (*oldest)->_path, _open, _max_open
                                        )
                                );
                }
 
                if (d->open ()) {
-                       DEBUG_TRACE (DEBUG::FileManager, string_compose ("open of %1 failed.\n", d->_name));
+                       DEBUG_TRACE (DEBUG::FileManager, string_compose ("open of %1 failed.\n", d->_path));
                        return true;
                }
 
                _open++;
 
-               DEBUG_TRACE (DEBUG::FileManager, string_compose ("opened file for %1; now have %2 of %3 open.\n", d->_name, _open, _max_open));
+               DEBUG_TRACE (DEBUG::FileManager, string_compose ("opened file for %1; now have %2 of %3 open.\n", d->_path, _open, _max_open));
        }
 
+#ifdef __APPLE__
+       d->_last_used = mach_absolute_time();
+#elif defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
        struct timespec t;
        clock_gettime (CLOCK_MONOTONIC, &t);
        d->_last_used = t.tv_sec + (double) t.tv_nsec / 10e9;
+#else
+       struct timeval now;
+       gettimeofday (&now, NULL);
+       d->_last_used = now.tv_sec + (double) now.tv_usec / 10e6;
+#endif
 
        d->_refcount++;
        
@@ -148,7 +137,7 @@ FileManager::allocate (FileDescriptor* d)
 void
 FileManager::release (FileDescriptor* d)
 {
-       Glib::Mutex::Lock lm (_mutex);
+       Glib::Threads::Mutex::Lock lm (_mutex);
 
        d->_refcount--;
        assert (d->_refcount >= 0);
@@ -158,13 +147,13 @@ FileManager::release (FileDescriptor* d)
 void
 FileManager::remove (FileDescriptor* d)
 {
-       Glib::Mutex::Lock lm (_mutex);
+       Glib::Threads::Mutex::Lock lm (_mutex);
 
        if (d->is_open ()) {
                close (d);
                DEBUG_TRACE (
                        DEBUG::FileManager,
-                       string_compose ("closed file for %1; file is being removed; now have %2 of %3 open\n", d->_name, _open, _max_open)
+                       string_compose ("closed file for %1; file is being removed; now have %2 of %3 open\n", d->_path, _open, _max_open)
                        );
        }
 
@@ -184,7 +173,7 @@ FileManager::close (FileDescriptor* d)
 FileDescriptor::FileDescriptor (string const & n, bool w)
        : _refcount (0)
        , _last_used (0)
-       , _name (n)
+       , _path (n)
        , _writeable (w)
 {
 
@@ -207,75 +196,17 @@ FileDescriptor::release ()
        manager()->release (this);
 }
 
-/** @param n Filename.
- *  @param w true to open writeable, otherwise false.
- *  @param i SF_INFO for the file.
- */
 
-SndFileDescriptor::SndFileDescriptor (string const & n, bool w, SF_INFO* i)
-       : FileDescriptor (n, w)
-       , _sndfile (0)
-       , _info (i)
-{
-       manager()->add (this);
-}
-
-SndFileDescriptor::~SndFileDescriptor ()
-{
-       manager()->remove (this);
-}
-
-/** @return SNDFILE*, or 0 on error */
-SNDFILE*
-SndFileDescriptor::allocate ()
-{
-       bool const f = manager()->allocate (this);
-       if (f) {
-               return 0;
-       }
 
-       /* this is ok thread-wise because allocate () has incremented
-          the Descriptor's refcount, so the file will not be closed
-       */
-       return _sndfile;
-}
-
-void
-SndFileDescriptor::close ()
-{
-       /* we must have a lock on the FileManager's mutex */
-
-       sf_close (_sndfile);
-       _sndfile = 0;
-}
-
-bool
-SndFileDescriptor::is_open () const
-{
-       /* we must have a lock on the FileManager's mutex */
-
-       return _sndfile != 0;
-}
-
-bool
-SndFileDescriptor::open ()
-{
-       /* we must have a lock on the FileManager's mutex */
-       
-       _sndfile = sf_open (_name.c_str(), _writeable ? SFM_RDWR : SFM_READ, _info);
-       return (_sndfile == 0);
-}
-
-
-/** @param n Filename.
- *  @param w true to open writeable, otherwise false.
- *  @param m Open mode for the file.
+/** @param file_name Filename.
+ *  @param writeable true to open writeable, otherwise false.
+ *  @param mode Open mode for the file.
  */
 
-FdFileDescriptor::FdFileDescriptor (string const & n, bool w, mode_t m)
-       : FileDescriptor (n, w)
+FdFileDescriptor::FdFileDescriptor (string const & file_name, bool writeable, mode_t mode)
+       : FileDescriptor (file_name, writeable)
        , _fd (-1)
-       , _mode (m)
+       , _mode (mode)
 {
        manager()->add (this);
 }
@@ -297,8 +228,19 @@ bool
 FdFileDescriptor::open ()
 {
        /* we must have a lock on the FileManager's mutex */
-       
-       _fd = ::open (_name.c_str(), _writeable ? (O_RDWR | O_CREAT) : O_RDONLY, _mode);
+
+       /* files must be opened with O_BINARY flag on windows
+        * or it treats the file as a text stream and puts in
+        * line endings in etc
+        */
+#ifdef WIN32
+#define WRITE_FLAGS O_RDWR | O_CREAT | O_BINARY
+#define READ_FLAGS O_RDONLY | O_BINARY
+#else
+#define WRITE_FLAGS O_RDWR | O_CREAT
+#define READ_FLAGS O_RDONLY
+#endif
+       _fd = ::g_open (_path.c_str(), _writeable ? WRITE_FLAGS : READ_FLAGS, _mode);
        return (_fd == -1);
 }
 
@@ -327,14 +269,20 @@ FdFileDescriptor::allocate ()
 }
 
 
-/** @param n Filename.
- *  @param w true to open writeable, otherwise false.
+void
+FileDescriptor::set_path (const string& p)
+{
+        _path = p;
+}
+
+/** @param file_name Filename.
+ *  @param mode Mode to pass to fopen.
  */
 
-StdioFileDescriptor::StdioFileDescriptor (string const & n, std::string const & m)
-       : FileDescriptor (n, false)
+StdioFileDescriptor::StdioFileDescriptor (string const & file_name, std::string const & mode)
+       : FileDescriptor (file_name, false)
        , _file (0)
-       , _mode (m)
+       , _mode (mode)
 {
        manager()->add (this);
 }
@@ -357,7 +305,7 @@ StdioFileDescriptor::open ()
 {
        /* we must have a lock on the FileManager's mutex */
        
-       _file = fopen (_name.c_str(), _mode.c_str());
+       _file = fopen (_path.c_str(), _mode.c_str());
        return (_file == 0);
 }