diff options
author | Jesse Morgan <jesse@jesterpm.net> | 2016-12-17 21:28:53 -0800 |
---|---|---|
committer | Jesse Morgan <jesse@jesterpm.net> | 2016-12-17 21:28:53 -0800 |
commit | 54df2afaa61c6a03cbb4a33c9b90fa572b6d07b8 (patch) | |
tree | 18147b92b969d25ffbe61935fb63035cac820dd0 /db-4.8.30/os_windows/os_handle.c |
Berkeley DB 4.8 with rust build script for linux.
Diffstat (limited to 'db-4.8.30/os_windows/os_handle.c')
-rw-r--r-- | db-4.8.30/os_windows/os_handle.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/db-4.8.30/os_windows/os_handle.c b/db-4.8.30/os_windows/os_handle.c new file mode 100644 index 0000000..74681e3 --- /dev/null +++ b/db-4.8.30/os_windows/os_handle.c @@ -0,0 +1,165 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1998-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * __os_openhandle -- + * Open a file, using POSIX 1003.1 open flags. + */ +int +__os_openhandle(env, name, flags, mode, fhpp) + ENV *env; + const char *name; + int flags, mode; + DB_FH **fhpp; +{ +#ifdef DB_WINCE + /* + * __os_openhandle API is not implemented on WinCE. + * It is not currently called from within the Berkeley DB library, + * so don't log the failure via the __db_err mechanism. + */ + return (EFAULT); +#else + DB_FH *fhp; + int ret, nrepeat, retries; + + /* + * Allocate the file handle and copy the file name. We generally only + * use the name for verbose or error messages, but on systems where we + * can't unlink temporary files immediately, we use the name to unlink + * the temporary file when the file handle is closed. + * + * Lock the ENV handle and insert the new file handle on the list. + */ + if ((ret = __os_calloc(env, 1, sizeof(DB_FH), &fhp)) != 0) + return (ret); + if ((ret = __os_strdup(env, name, &fhp->name)) != 0) + goto err; + if (env != NULL) { + MUTEX_LOCK(env, env->mtx_env); + TAILQ_INSERT_TAIL(&env->fdlist, fhp, q); + MUTEX_UNLOCK(env, env->mtx_env); + F_SET(fhp, DB_FH_ENVLINK); + } + + retries = 0; + for (nrepeat = 1; nrepeat < 4; ++nrepeat) { + fhp->fd = _open(name, flags, mode); + + if (fhp->fd != -1) { + ret = 0; + break; + } + + switch (ret = __os_posix_err(__os_get_syserr())) { + case EMFILE: + case ENFILE: + case ENOSPC: + /* + * If it's a "temporary" error, we retry up to 3 times, + * waiting up to 12 seconds. While it's not a problem + * if we can't open a database, an inability to open a + * log file is cause for serious dismay. + */ + __os_yield(env, nrepeat * 2, 0); + break; + case EAGAIN: + case EBUSY: + case EINTR: + /* + * If an EAGAIN, EBUSY or EINTR, retry immediately for + * DB_RETRY times. + */ + if (++retries < DB_RETRY) + --nrepeat; + break; + default: + /* Open is silent on error. */ + goto err; + } + } + + if (ret == 0) { + F_SET(fhp, DB_FH_OPENED); + *fhpp = fhp; + return (0); + } + +err: (void)__os_closehandle(env, fhp); + return (ret); +#endif +} + +/* + * __os_closehandle -- + * Close a file. + */ +int +__os_closehandle(env, fhp) + ENV *env; + DB_FH *fhp; +{ + DB_ENV *dbenv; + int ret, t_ret; + + ret = 0; + + if (env != NULL) { + dbenv = env->dbenv; + if (fhp->name != NULL && FLD_ISSET( + dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL)) + __db_msg(env, "fileops: %s: close", fhp->name); + + if (F_ISSET(fhp, DB_FH_ENVLINK)) { + /* + * Lock the ENV handle and remove this file + * handle from the list. + */ + MUTEX_LOCK(env, env->mtx_env); + TAILQ_REMOVE(&env->fdlist, fhp, q); + MUTEX_UNLOCK(env, env->mtx_env); + } + } + + /* Discard any underlying system file reference. */ + if (F_ISSET(fhp, DB_FH_OPENED)) { + if (fhp->handle != INVALID_HANDLE_VALUE) + RETRY_CHK((!CloseHandle(fhp->handle)), ret); + else +#ifdef DB_WINCE + ret = EFAULT; +#else + RETRY_CHK((_close(fhp->fd)), ret); +#endif + + if (fhp->trunc_handle != INVALID_HANDLE_VALUE) { + RETRY_CHK((!CloseHandle(fhp->trunc_handle)), t_ret); + if (t_ret != 0 && ret == 0) + ret = t_ret; + } + + if (ret != 0) { + __db_syserr(env, ret, "CloseHandle"); + ret = __os_posix_err(ret); + } + } + + /* Unlink the file if we haven't already done so. */ + if (F_ISSET(fhp, DB_FH_UNLINK)) + (void)__os_unlink(env, fhp->name, 0); + + if (fhp->name != NULL) + __os_free(env, fhp->name); + __os_free(env, fhp); + + return (ret); +} |