/* * __wt_close -- * Close a file handle. */ int __wt_close(WT_SESSION_IMPL *session, WT_FH **fhp) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_FH *fh; uint64_t bucket; conn = S2C(session); if (*fhp == NULL) return (0); fh = *fhp; *fhp = NULL; __wt_spin_lock(session, &conn->fh_lock); if (fh == NULL || fh->ref == 0 || --fh->ref > 0) { __wt_spin_unlock(session, &conn->fh_lock); return (0); } /* Remove from the list. */ bucket = fh->name_hash % WT_HASH_ARRAY_SIZE; WT_CONN_FILE_REMOVE(conn, fh, bucket); (void)WT_ATOMIC_SUB4(conn->open_file_count, 1); __wt_spin_unlock(session, &conn->fh_lock); /* Discard the memory. * Note: For directories, we do not open valid directory handles on * windows since it is not possible to sync a directory */ if (fh->filehandle != INVALID_HANDLE_VALUE && CloseHandle(fh->filehandle) == 0) { ret = __wt_errno(); __wt_err(session, ret, "CloseHandle: %s", fh->name); } if (fh->filehandle_secondary != INVALID_HANDLE_VALUE && CloseHandle(fh->filehandle_secondary) == 0) { ret = __wt_errno(); __wt_err(session, ret, "CloseHandle: secondary: %s", fh->name); } __wt_free(session, fh->name); __wt_free(session, fh); return (ret); }
/* * __wt_close -- * Close a file handle. */ int __wt_close(WT_SESSION_IMPL *session, WT_FH **fhp) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_FH *fh; uint64_t bucket; conn = S2C(session); if (*fhp == NULL) return (0); fh = *fhp; *fhp = NULL; /* Track handle-close as a file operation, so open and close match. */ WT_RET(__wt_verbose( session, WT_VERB_FILEOPS, "%s: handle-close", fh->name)); /* * If the reference count hasn't gone to 0, or if it's an in-memory * object, we're done. * * Assert the reference count is correct, but don't let it wrap. */ __wt_spin_lock(session, &conn->fh_lock); WT_ASSERT(session, fh->ref > 0); if ((fh->ref > 0 && --fh->ref > 0) || F_ISSET(fh, WT_FH_IN_MEMORY)) { __wt_spin_unlock(session, &conn->fh_lock); return (0); } /* Remove from the list. */ bucket = fh->name_hash % WT_HASH_ARRAY_SIZE; WT_CONN_FILE_REMOVE(conn, fh, bucket); (void)__wt_atomic_sub32(&conn->open_file_count, 1); __wt_spin_unlock(session, &conn->fh_lock); /* Discard underlying resources. */ ret = fh->fh_close(session, fh); __wt_free(session, fh->name); __wt_free(session, fh); return (ret); }