… | |
… | |
39 | #include <fcntl.h> // for locking |
39 | #include <fcntl.h> // for locking |
40 | |
40 | |
41 | #include <sys/stat.h> |
41 | #include <sys/stat.h> |
42 | #include <sys/types.h> |
42 | #include <sys/types.h> |
43 | #include <dirent.h> |
43 | #include <dirent.h> |
|
|
44 | #include <utime.h> |
44 | |
45 | |
45 | #include "md5.h" |
46 | #include "md5.h" |
46 | |
47 | |
47 | #include <dlfcn.h> |
48 | #include <dlfcn.h> |
48 | |
49 | |
… | |
… | |
74 | const char typestr<I32 *>::str[] = STR(TYPE_INT32) " *"; |
75 | const char typestr<I32 *>::str[] = STR(TYPE_INT32) " *"; |
75 | const char typestr<I64 *>::str[] = STR(TYPE_INT64) " *"; |
76 | const char typestr<I64 *>::str[] = STR(TYPE_INT64) " *"; |
76 | const char typestr<FLT *>::str[] = "float" " *"; |
77 | const char typestr<FLT *>::str[] = "float" " *"; |
77 | const char typestr<DBL *>::str[] = "double" " *"; |
78 | const char typestr<DBL *>::str[] = "double" " *"; |
78 | |
79 | |
|
|
80 | ///////////////////////////////////////////////////////////////////////////// |
|
|
81 | |
79 | struct digest : md5_ctx |
82 | struct digest : md5_ctx |
80 | { |
83 | { |
81 | digest (); |
84 | digest (); |
82 | void operator ()(const std::string &data); |
85 | void operator ()(const std::string &data); |
83 | operator std::string(); |
86 | operator std::string(); |
… | |
… | |
104 | s << std::setfill ('0') << std::hex << std::setw (2) << (int)data [i]; |
107 | s << std::setfill ('0') << std::hex << std::setw (2) << (int)data [i]; |
105 | |
108 | |
106 | return s.str (); |
109 | return s.str (); |
107 | } |
110 | } |
108 | |
111 | |
|
|
112 | ///////////////////////////////////////////////////////////////////////////// |
|
|
113 | |
109 | static inline bool |
114 | static inline bool |
110 | is_null (const std::string &s) |
115 | is_null (const std::string &s) |
111 | { |
116 | { |
112 | return s.empty (); |
117 | return s.empty (); |
113 | } |
118 | } |
|
|
119 | |
|
|
120 | ///////////////////////////////////////////////////////////////////////////// |
114 | |
121 | |
115 | // error exception builder |
122 | // error exception builder |
116 | struct error : std::ostringstream |
123 | struct error : std::ostringstream |
117 | { |
124 | { |
118 | ~error () |
125 | ~error () |
… | |
… | |
121 | } |
128 | } |
122 | }; |
129 | }; |
123 | |
130 | |
124 | #define FATAL(msg) do { error o; o << msg << std::endl; } while (0) |
131 | #define FATAL(msg) do { error o; o << msg << std::endl; } while (0) |
125 | #define ERRNO " (" << strerror (errno) << ")" |
132 | #define ERRNO " (" << strerror (errno) << ")" |
|
|
133 | |
|
|
134 | ///////////////////////////////////////////////////////////////////////////// |
|
|
135 | |
|
|
136 | static long get_stamp (int fd) |
|
|
137 | { |
|
|
138 | struct stat st; |
|
|
139 | |
|
|
140 | if (fstat (fd, &st)) |
|
|
141 | FATAL ("could not get file stamp"); |
|
|
142 | |
|
|
143 | return (long)st.st_mtime; |
|
|
144 | } |
|
|
145 | |
|
|
146 | static void set_stamp (const std::string &path, long stamp) |
|
|
147 | { |
|
|
148 | struct utimbuf ut; |
|
|
149 | |
|
|
150 | ut.actime = stamp; |
|
|
151 | ut.modtime = stamp; |
|
|
152 | |
|
|
153 | if (utime (path.c_str (), &ut)) |
|
|
154 | FATAL ("could not set file stamp"); |
|
|
155 | } |
126 | |
156 | |
127 | env::env (const std::string &path, bool temporary) |
157 | env::env (const std::string &path, bool temporary) |
128 | : path(path), temporary(temporary) |
158 | : path(path), temporary(temporary) |
129 | { |
159 | { |
130 | mode_t oflags = O_RDWR | O_EXCL; |
160 | mode_t oflags = O_RDWR | O_EXCL; |
… | |
… | |
140 | oflags |= O_CREAT; |
170 | oflags |= O_CREAT; |
141 | else |
171 | else |
142 | if (temporary) |
172 | if (temporary) |
143 | FATAL ("error while creating libcpjit temporary directory" << ERRNO); |
173 | FATAL ("error while creating libcpjit temporary directory" << ERRNO); |
144 | |
174 | |
145 | std::string index = this->path + "/libcpjit.idx"; |
175 | idxpath = this->path + "/libcpjit.idx"; |
146 | idxfd = open (index.c_str (), oflags, 0666); |
176 | idxfd = open (idxpath.c_str (), oflags, 0666); |
147 | if (idxfd < 0) |
177 | if (idxfd < 0) |
148 | FATAL (path << ": unable to open index file" << index); |
178 | FATAL (path << ": unable to open index file" << idxpath); |
149 | |
179 | |
150 | lock (); |
180 | lock (); |
151 | load_index (); |
181 | load_index (); |
152 | unlock (); |
182 | unlock (); |
153 | } |
183 | } |
… | |
… | |
206 | } |
236 | } |
207 | |
237 | |
208 | void |
238 | void |
209 | env::load_index () |
239 | env::load_index () |
210 | { |
240 | { |
|
|
241 | // caller must lock() |
|
|
242 | |
|
|
243 | long stamp = get_stamp (idxfd); |
|
|
244 | |
|
|
245 | if (stamp == idxstamp) |
|
|
246 | return; |
|
|
247 | |
|
|
248 | idxstamp = stamp; |
|
|
249 | |
|
|
250 | // ... TODO |
|
|
251 | |
211 | } |
252 | } |
212 | |
253 | |
213 | void |
254 | void |
214 | env::save_index () |
255 | env::save_index () |
215 | { |
256 | { |
216 | std::ifstream f ((this->path + "/libcpjit.idx").c_str ()); |
257 | // caller must lock()+load_index() |
217 | assert (("not a cpjit directory", f)); |
258 | |
218 | f.close (); |
259 | // ... TODO |
|
|
260 | set_stamp (idxpath, ++idxstamp); |
219 | } |
261 | } |
|
|
262 | |
|
|
263 | ///////////////////////////////////////////////////////////////////////////// |
220 | |
264 | |
221 | fun::fun (env &e, const std::string &id, const std::string &source) |
265 | fun::fun (env &e, const std::string &id, const std::string &source) |
222 | : e(e), id(id), source(source), funptr(0) |
266 | : e(e), id(id), source(source), funptr(0) |
223 | { |
267 | { |
224 | } |
268 | } |
… | |
… | |
259 | e.unlock (); |
303 | e.unlock (); |
260 | } |
304 | } |
261 | |
305 | |
262 | return funptr; |
306 | return funptr; |
263 | } |
307 | } |
|
|
308 | |
|
|
309 | ///////////////////////////////////////////////////////////////////////////// |
264 | |
310 | |
265 | funbuild::funbuild (env &e, const char *rettype, ...) |
311 | funbuild::funbuild (env &e, const char *rettype, ...) |
266 | : e(e) |
312 | : e(e) |
267 | { |
313 | { |
268 | retlist = rettype; |
314 | retlist = rettype; |