00001
00034 #include "linden_common.h"
00035 #include "llapr.h"
00036
00037 apr_pool_t *gAPRPoolp = NULL;
00038 apr_thread_mutex_t *gLogMutexp = NULL;
00039
00040
00041 void ll_init_apr()
00042 {
00043 if (!gAPRPoolp)
00044 {
00045
00046 apr_initialize();
00047 apr_pool_create(&gAPRPoolp, NULL);
00048
00049
00050 apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
00051 }
00052 }
00053
00054
00055 void ll_cleanup_apr()
00056 {
00057 LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
00058
00059 if (gLogMutexp)
00060 {
00061
00062
00063
00064 apr_thread_mutex_destroy(gLogMutexp);
00065 gLogMutexp = NULL;
00066 }
00067 if (gAPRPoolp)
00068 {
00069 apr_pool_destroy(gAPRPoolp);
00070 gAPRPoolp = NULL;
00071 }
00072 apr_terminate();
00073 }
00074
00075
00076
00077
00078 LLScopedLock::LLScopedLock(apr_thread_mutex_t* mutex) : mMutex(mutex)
00079 {
00080 if(mutex)
00081 {
00082 if(ll_apr_warn_status(apr_thread_mutex_lock(mMutex)))
00083 {
00084 mLocked = false;
00085 }
00086 else
00087 {
00088 mLocked = true;
00089 }
00090 }
00091 else
00092 {
00093 mLocked = false;
00094 }
00095 }
00096
00097 LLScopedLock::~LLScopedLock()
00098 {
00099 unlock();
00100 }
00101
00102 void LLScopedLock::unlock()
00103 {
00104 if(mLocked)
00105 {
00106 if(!ll_apr_warn_status(apr_thread_mutex_unlock(mMutex)))
00107 {
00108 mLocked = false;
00109 }
00110 }
00111 }
00112
00113
00114
00115
00116 bool ll_apr_warn_status(apr_status_t status)
00117 {
00118 if(APR_SUCCESS == status) return false;
00119 #ifndef LL_WINDOWS
00120 char buf[MAX_STRING];
00121 LL_WARNS_ONCE("APR") << "APR: " << apr_strerror(status, buf, MAX_STRING) << LL_ENDL;
00122 #endif
00123 return true;
00124 }
00125
00126 void ll_apr_assert_status(apr_status_t status)
00127 {
00128 llassert(ll_apr_warn_status(status) == false);
00129 }
00130
00131
00132 apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, S32* sizep, apr_pool_t* pool)
00133 {
00134 apr_file_t* apr_file;
00135 apr_status_t s;
00136 if (pool == NULL) pool = gAPRPoolp;
00137 s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool);
00138 if (s != APR_SUCCESS)
00139 {
00140 if (sizep)
00141 {
00142 *sizep = 0;
00143 }
00144 return NULL;
00145 }
00146
00147 if (sizep)
00148 {
00149 S32 file_size = 0;
00150 apr_off_t offset = 0;
00151 if (apr_file_seek(apr_file, APR_END, &offset) == APR_SUCCESS)
00152 {
00153 llassert_always(offset <= 0x7fffffff);
00154 file_size = (S32)offset;
00155 offset = 0;
00156 apr_file_seek(apr_file, APR_SET, &offset);
00157 }
00158 *sizep = file_size;
00159 }
00160
00161 return apr_file;
00162 }
00163 apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, S32* sizep)
00164 {
00165 return ll_apr_file_open(filename, flags, sizep, NULL);
00166 }
00167 apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags, apr_pool_t* pool)
00168 {
00169 return ll_apr_file_open(filename, flags, NULL, pool);
00170 }
00171 apr_file_t* ll_apr_file_open(const LLString& filename, apr_int32_t flags)
00172 {
00173 return ll_apr_file_open(filename, flags, NULL, NULL);
00174 }
00175
00176 S32 ll_apr_file_read(apr_file_t* apr_file, void *buf, S32 nbytes)
00177 {
00178 apr_size_t sz = nbytes;
00179 apr_status_t s = apr_file_read(apr_file, buf, &sz);
00180 if (s != APR_SUCCESS)
00181 {
00182 return 0;
00183 }
00184 else
00185 {
00186 llassert_always(sz <= 0x7fffffff);
00187 return (S32)sz;
00188 }
00189 }
00190
00191 S32 ll_apr_file_read_ex(const LLString& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes)
00192 {
00193 if (pool == NULL) pool = gAPRPoolp;
00194 apr_file_t* filep = ll_apr_file_open(filename, APR_READ|APR_BINARY, pool);
00195 if (!filep)
00196 {
00197 return 0;
00198 }
00199 S32 off;
00200 if (offset < 0)
00201 off = ll_apr_file_seek(filep, APR_END, 0);
00202 else
00203 off = ll_apr_file_seek(filep, APR_SET, offset);
00204 S32 bytes_read;
00205 if (off < 0)
00206 {
00207 bytes_read = 0;
00208 }
00209 else
00210 {
00211 bytes_read = ll_apr_file_read(filep, buf, nbytes );
00212 }
00213 apr_file_close(filep);
00214
00215 return bytes_read;
00216 }
00217
00218 S32 ll_apr_file_write(apr_file_t* apr_file, const void *buf, S32 nbytes)
00219 {
00220 apr_size_t sz = nbytes;
00221 apr_status_t s = apr_file_write(apr_file, buf, &sz);
00222 if (s != APR_SUCCESS)
00223 {
00224 return 0;
00225 }
00226 else
00227 {
00228 llassert_always(sz <= 0x7fffffff);
00229 return (S32)sz;
00230 }
00231 }
00232
00233 S32 ll_apr_file_write_ex(const LLString& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes)
00234 {
00235 if (pool == NULL) pool = gAPRPoolp;
00236 apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
00237 if (offset < 0)
00238 {
00239 flags |= APR_APPEND;
00240 offset = 0;
00241 }
00242 apr_file_t* filep = ll_apr_file_open(filename, flags, pool);
00243 if (!filep)
00244 {
00245 return 0;
00246 }
00247 if (offset > 0)
00248 {
00249 offset = ll_apr_file_seek(filep, APR_SET, offset);
00250 }
00251 S32 bytes_written;
00252 if (offset < 0)
00253 {
00254 bytes_written = 0;
00255 }
00256 else
00257 {
00258 bytes_written = ll_apr_file_write(filep, buf, nbytes );
00259 }
00260 apr_file_close(filep);
00261
00262 return bytes_written;
00263 }
00264
00265 S32 ll_apr_file_seek(apr_file_t* apr_file, apr_seek_where_t where, S32 offset)
00266 {
00267 apr_status_t s;
00268 apr_off_t apr_offset;
00269 if (offset >= 0)
00270 {
00271 apr_offset = (apr_off_t)offset;
00272 s = apr_file_seek(apr_file, where, &apr_offset);
00273 }
00274 else
00275 {
00276 apr_offset = 0;
00277 s = apr_file_seek(apr_file, APR_END, &apr_offset);
00278 }
00279 if (s != APR_SUCCESS)
00280 {
00281 return -1;
00282 }
00283 else
00284 {
00285 llassert_always(apr_offset <= 0x7fffffff);
00286 return (S32)apr_offset;
00287 }
00288 }
00289
00290 bool ll_apr_file_remove(const LLString& filename, apr_pool_t* pool)
00291 {
00292 apr_status_t s;
00293 if (pool == NULL) pool = gAPRPoolp;
00294 s = apr_file_remove(filename.c_str(), pool);
00295 if (s != APR_SUCCESS)
00296 {
00297 LL_DEBUGS("APR") << "ll_apr_file_remove failed on file: " << filename << LL_ENDL;
00298 ll_apr_warn_status(s);
00299 return false;
00300 }
00301 return true;
00302 }
00303
00304 bool ll_apr_file_rename(const LLString& filename, const LLString& newname, apr_pool_t* pool)
00305 {
00306 apr_status_t s;
00307 if (pool == NULL) pool = gAPRPoolp;
00308 s = apr_file_rename(filename.c_str(), newname.c_str(), pool);
00309 if (s != APR_SUCCESS)
00310 {
00311 LL_DEBUGS("APR") << "ll_apr_file_rename failed on file: " << filename << LL_ENDL;
00312 ll_apr_warn_status(s);
00313 return false;
00314 }
00315 return true;
00316 }
00317
00318 bool ll_apr_file_exists(const LLString& filename, apr_pool_t* pool)
00319 {
00320 apr_file_t* apr_file;
00321 apr_status_t s;
00322 if (pool == NULL) pool = gAPRPoolp;
00323 s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool);
00324 if (s != APR_SUCCESS || !apr_file)
00325 {
00326 return false;
00327 }
00328 else
00329 {
00330 apr_file_close(apr_file);
00331 return true;
00332 }
00333 }
00334
00335 S32 ll_apr_file_size(const LLString& filename, apr_pool_t* pool)
00336 {
00337 apr_file_t* apr_file;
00338 apr_finfo_t info;
00339 apr_status_t s;
00340 if (pool == NULL) pool = gAPRPoolp;
00341 s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool);
00342 if (s != APR_SUCCESS || !apr_file)
00343 {
00344 return 0;
00345 }
00346 else
00347 {
00348 apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);
00349 apr_file_close(apr_file);
00350 if (s == APR_SUCCESS)
00351 {
00352 return (S32)info.size;
00353 }
00354 else
00355 {
00356 return 0;
00357 }
00358 }
00359 }
00360
00361 bool ll_apr_dir_make(const LLString& dirname, apr_pool_t* pool)
00362 {
00363 apr_status_t s;
00364 if (pool == NULL) pool = gAPRPoolp;
00365 s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool);
00366 if (s != APR_SUCCESS)
00367 {
00368 LL_DEBUGS("APR") << "ll_apr_dir_make failed on file: " << dirname << LL_ENDL;
00369 ll_apr_warn_status(s);
00370 return false;
00371 }
00372 return true;
00373 }
00374
00375 bool ll_apr_dir_remove(const LLString& dirname, apr_pool_t* pool)
00376 {
00377 apr_status_t s;
00378 if (pool == NULL) pool = gAPRPoolp;
00379 s = apr_file_remove(dirname.c_str(), pool);
00380 if (s != APR_SUCCESS)
00381 {
00382 LL_DEBUGS("APR") << "ll_apr_dir_remove failed on file: " << dirname << LL_ENDL;
00383 ll_apr_warn_status(s);
00384 return false;
00385 }
00386 return true;
00387 }
00388