fix some cast warnings
[ardour.git] / libs / pbd / pbd / file_manager.h
1 /*
2     Copyright (C) 2010 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef __pbd_file_manager_h__
21 #define __pbd_file_manager_h__
22
23 #include <sys/types.h>
24 #include <string>
25 #include <map>
26 #include <list>
27 #include <glibmm/threads.h>
28
29 #include "pbd/libpbd_visibility.h"
30 #include "pbd/signals.h"
31
32 namespace PBD {
33
34 class LIBPBD_API FileManager;
35
36 /** Parent class for FileDescriptors.
37  *
38  *  When a subclass is instantiated, the file it describes is added to a
39  *  list.  The FileDescriptor can be `allocated', meaning that its
40  *  file will be opened on the filesystem, and can then be `released'.
41  *  FileDescriptors are reference counted as they are allocated and
42  *  released.  When a descriptor's refcount is 0, the file on the
43  *  filesystem is eligible to be closed if necessary to free up file
44  *  handles for other files.
45  *
46  *  The upshot of all this is that Ardour can manage the number of
47  *  open files to stay within limits imposed by the operating system.
48  */
49         
50 class LIBPBD_API FileDescriptor
51 {
52 public:
53         FileDescriptor (std::string const &, bool);
54         virtual ~FileDescriptor () {}
55
56         const std::string& path() const { return _path; }
57
58         void release ();
59         virtual void set_path (const std::string&);
60
61         /** Emitted when the file is closed */
62         PBD::Signal0<void> Closed;
63
64 protected:
65
66         friend class FileManager;
67
68         /* These methods and variables must be called / accessed
69            with a lock held on the FileManager's mutex
70         */
71
72         /** @return false on success, true on failure */
73         virtual bool open () = 0;
74         virtual void close () = 0;
75         virtual bool is_open () const = 0;
76
77         int _refcount; ///< number of active users of this file
78         double _last_used; ///< monotonic time that this file was last allocated
79         std::string _path; ///< file path
80         bool _writeable; ///< true if it should be opened writeable, otherwise false
81
82         FileManager* manager ();
83         
84 private:
85         
86         static FileManager* _manager;
87 };
88
89
90 /** FileDescriptor for a file to be opened using POSIX open */  
91 class LIBPBD_API FdFileDescriptor : public FileDescriptor
92 {
93 public:
94         FdFileDescriptor (std::string const & file_name, bool writeable, mode_t mode);
95         ~FdFileDescriptor ();
96
97         int allocate ();
98
99 private:
100
101         friend class FileManager;
102
103         bool open ();
104         void close ();
105         bool is_open () const;
106
107         int _fd; ///< file descriptor, or -1 if the file is closed
108         mode_t _mode; ///< mode to use when creating files
109 };
110
111 /** FileDescriptor for a file opened using stdio */
112 class LIBPBD_API StdioFileDescriptor : public FileDescriptor
113 {
114 public:
115         StdioFileDescriptor (std::string const & file_name, std::string const & mode);
116         ~StdioFileDescriptor ();
117
118         FILE* allocate ();
119
120 private:
121
122         friend class FileManager;
123
124         bool open ();
125         void close ();
126         bool is_open () const;
127
128         FILE* _file;
129         std::string _mode;
130 };
131
132
133 /** Class to limit the number of files held open */
134 class LIBPBD_API FileManager
135 {
136 public:
137         FileManager ();
138         
139         void add (FileDescriptor *);
140         void remove (FileDescriptor *);
141
142         void release (FileDescriptor *);
143         bool allocate (FileDescriptor *);
144
145 private:
146         
147         void close (FileDescriptor *);
148
149         std::list<FileDescriptor*> _files; ///< files we know about
150         Glib::Threads::Mutex _mutex; ///< mutex for _files, _open and FileDescriptor contents
151         int _open; ///< number of open files
152         int _max_open; ///< maximum number of open files
153 };
154
155 }
156
157 #endif