enter.c
来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 1,824 行 · 第 1/4 页
C
1,824 行
/*************************************************************************** * * * db.* * * open source database kernel * * * * Copyright (c) 2000 Centura Software Corporation. All rights reserved. * * * * Use of this software, whether in source code format, or in executable, * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this * * distribution of source code files. * * * * Except as provided herein, the contents of this file are subject to the * * Centura Open Source Public License Version 1.0 (the "License"); you may * * not use this file except in compliance with the License. A copy of the * * License will be provided to you by Club ITTIA. * * * * Software distributed under the License is distributed on an "AS IS" * * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * * License for the specific language governing rights and limitations * * under the License. * * * * The Original Code is db.linux version 1.0, released February 29, 2000. * * * * The Initial Developer of the Original Code is Centura Software * * Corporation. Portions created by Centura Software Corporation are * * Copyright (C) 1984-2000 Centura Software Corporation. All Rights * * Reserved. * * * * This file contains modifications to the Original Code made by ITTIA. * * This file may only be used in accordance with the ITTIA DB.* V.2 * * License Agreement which is available at WWW.ITTIA.COM. * * * **************************************************************************/#undef RUNTIME#include "db.star.h"#include "rntmint.h"#ifdef DB_TRACE#include "apinames.h"#endif // DB_TRACE#if defined(DB_DEBUG)/* Uncomment the following line if you want debugging output to be held in RAM and flushed when the application terminates. This is useful for debugging problems related to timing, which may be affected by the delay caused by disk access. Do not use this feature if the application crashes, as the debugging output won't be flushed. *//* #define MEM_DEBUG 1 */#if defined(MEM_DEBUG)#define DEBUG_BUFLEN 32768#endif#endif/* ====================================================================== Called once at the beginning of each external function*/int INTERNAL_FCN db_enter(int api, int dbn, DB_TASK *task){ /* Validate task pointer */ if (ntask_check(task) < 0) return S_INVTASK; /* Check for reentrant use of task - this might happen if two threads shared the same DB_TASK, which is not allowed. It would also happen if the application called any d_ functions from its database error handler. */ if (task->inDBSTAR) return (task->db_status = S_REENTER); task->inDBSTAR = 1; /* db_status should be set to S_OKAY here (on entry to all d_ functions), and nowhere else, unless to overwrite an error value which is not applicable. */ task->errnum = task->db_status = S_OKAY; API_ENTER(api);#ifdef DBSTAT task->gen_stats.dbenter++;#endif if (dbn != VOID_DB) { if (!task->dbopen) return (dberr(S_DBOPEN)); if (dbn == CURR_DB || dbn == ALL_DBS) dbn = task->set_db; else { if (dbn < 0 || dbn >= task->no_of_dbs) return (dberr(S_INVDB)); } if (dbn != task->curr_db) { task->db_table[task->curr_db].curr_dbt_rec = task->curr_rec; task->db_table[task->curr_db].curr_dbt_ts = task->cr_time; task->curr_db_table = &task->db_table[task->curr_db = dbn]; task->curr_rn_table = &task->rn_table[task->curr_db]; task->curr_rec = task->curr_db_table->curr_dbt_rec; task->cr_time = task->curr_db_table->curr_dbt_ts; } }#ifdef DB_DEBUG if (task->db_debug & CACHE_CHECK) check_cache(DB_TEXT("at db_enter"), task);#endif return (task->db_status);}/* ====================================================================== Called at the end of each external function*/int INTERNAL_FCN db_exit(int code, DB_TASK *task){ if (code == S_INVTASK || code == S_REENTER) return code; API_EXIT(); task->inDBSTAR = 0; /* display any pending error */ if (task->errnum < 0) flush_dberr(task); // throw exception is ok from here return code;}#ifdef DB_TRACE/* ====================================================================== Return API function name (function must be defined because lockcomm.h may try to link with it)*/DB_TCHAR *INTERNAL_FCN dbstar_apistr(int api){ if (api >= DBSTAR_FIRST && api <= DBSTAR_LAST) return dbstar_api[api-DBSTAR_FIRST]; return NULL;}/* ====================================================================== These should be called using the FN_ENTER, FN_RETURN, and FN_EXIT macros because they do the check for task->db_trace.*/int INTERNAL_FCN api_enter(int fn, DB_TASK *task){ DB_TCHAR *name = dbstar_apistr(fn); db_printf(task, DB_TEXT("+ %s\n"), name ? name : DB_TEXT("?")); return db_indent(task);}int INTERNAL_FCN api_exit(DB_TASK *task){ return db_undent(task);}int INTERNAL_FCN fn_enter(DB_TCHAR *name, DB_TASK *task){ db_printf(task, DB_TEXT("+ %s\n"), name ? name : DB_TEXT("?")); return db_indent(task);}int INTERNAL_FCN fn_exit(DB_TASK *task){ return db_undent(task);}static int INTERNAL_FCN db_trace_write(PSP_FH, const DB_TCHAR *, size_t, DB_TASK *);/* ======================================================================*/int db_printf(DB_TASK *task, DB_TCHAR *fmt, ...){ static PSP_SEM debug_mutex = NO_PSP_SEM; static DB_TCHAR *debug_buf = NULL; static DB_TCHAR *debug_ptr = NULL; static unsigned int debug_len = 0; static DB_TCHAR *buf = NULL; static DB_TCHAR name[FILENMLEN] = DB_TEXT(""); static PSP_FH trace_fd = NULL; static off_t last_len = (off_t)-1; static int eol = TRUE; int stat = S_OKAY; if (debug_mutex == NO_PSP_SEM) debug_mutex = psp_syncCreate(PSP_MUTEX_SEM); psp_syncEnterExcl(debug_mutex); if (!fmt) /* cleanup */ {#ifdef MEM_DEBUG if (debug_buf) { if (!trace_fd) trace_fd = psp_fileOpen(name, O_WRONLY | O_CREAT, PSP_FLAG_DENYNO); if (trace_fd) { db_trace_write(trace_fd, debug_buf, debug_len, task); psp_fileClose(trace_fd); } trace_fd = NULL; psp_freeMemory(debug_buf, 0); debug_buf = debug_ptr = NULL; debug_len = 0; }#else if (trace_fd != NULL) psp_fileClose(trace_fd); trace_fd = NULL;#endif if (buf) psp_zFreeMemory(&buf, 0); psp_syncExitExcl(debug_mutex); psp_syncDelete(debug_mutex); debug_mutex = NO_PSP_SEM; return (stat == S_OKAY) ? TRUE : FALSE; } /* initialize */ if (!buf) { if ((buf = psp_cGetMemory(512 * sizeof(DB_TCHAR), 0)) == NULL) { psp_syncExitExcl(debug_mutex); return FALSE; } } if (!name[0]) { DB_TCHAR *path, *last; path = psp_getenv(DB_TEXT("DBTPATH")); if (path && *path) { vtstrcpy(name, path); last = &name[vtstrlen(name) - 1]; if (*last++ != DIRCHAR) *last++ = DIRCHAR; } else last = vtstrcpy(name, DB_TEXT("")); vtstrcat(last, DB_TEXT("db.star.out")); } #ifdef MEM_DEBUG if (!debug_buf) { debug_buf = psp_cGetMemory(DEBUG_BUFLEN * sizeof(DB_TCHAR), 0); if (debug_buf == NULL) { psp_syncExitExcl(debug_mutex); return FALSE; } debug_ptr = debug_buf; }#else if (trace_fd == NULL) { trace_fd = psp_fileOpen(name, O_WRONLY | O_CREAT, PSP_FLAG_DENYNO); if (trace_fd == NULL) { psp_syncExitExcl(debug_mutex); return FALSE; } }#endif#ifdef MEM_DEBUG if (debug_buf)#else if (trace_fd != NULL)#endif { DB_TCHAR *line, *pos; va_list args;#ifndef MEM_DEBUG off_t filelen;#endif static int last_task_no = -1; int task_no;#ifndef MEM_DEBUG psp_fileSeek(trace_fd, 0); psp_fileLock(trace_fd); filelen = psp_fileLength(trace_fd); psp_fileSeek(trace_fd, filelen); task_no = ntask_check(task); if (filelen != last_len || task_no != last_task_no) { DB_TCHAR task_id[80]; DB_TCHAR *ptr = task_id; if (!eol) ptr += vstprintf(ptr, DB_TEXT("\r\n")); ptr += vstprintf(ptr, DB_TEXT("<pid=%lx"), (long) psp_get_pid()); ptr += vstprintf(ptr, DB_TEXT(", task: %d"), task_no); if (task->dbuserid[0]) ptr += vstprintf(ptr, DB_TEXT(", user=%s"), task->dbuserid); else { DB_TCHAR *user = psp_getenv(DB_TEXT("DBUSERID")); ptr += vstprintf(ptr, DB_TEXT(", user=%s(?)"), user ? user : DB_TEXT("")); } vstprintf(ptr, DB_TEXT(">\r\n")); if (db_trace_write(trace_fd, task_id, vtstrlen(task_id), task) != (int)vtstrlen(task_id), task) return FALSE; last_task_no = task_no; eol = TRUE; /* force to new line */ }#endif /* MEM_DEBUG */ va_start(args, fmt); vvstprintf(buf, fmt, args); line = buf; do { int space = task->db_indent; if (eol) { while (space-- > 0) {#ifdef MEM_DEBUG if (debug_len >= DEBUG_BUFLEN - 3) { if (trace_fd == NULL) trace_fd = psp_fileOpen(name, O_WRONLY | O_CREAT, PSP_FLAG_DENYNO); if (trace_fd != NULL) stat = db_trace_write(trace_fd, debug_buf, debug_len, task); debug_ptr = debug_buf; debug_len = 0; } vtstrcpy(debug_ptr, DB_TEXT(" ")); debug_ptr += 2; debug_len += 2;#else stat = db_trace_write(trace_fd, DB_TEXT(" "), 2, task);#endif if (stat < 0) return FALSE; } } pos = vtstrchr(line, DB_TEXT('\n')); if (pos) *pos = 0; eol = (pos != NULL);#ifdef MEM_DEBUG if (debug_len >= DEBUG_BUFLEN - vtstrlen(line) - 1) { if (!trace_fd) trace_fd = psp_fileOpen(name, O_WRONLY | O_CREAT, PSP_FLAG_DENYNO); if (trace_fd) stat = db_trace_write(trace_fd, debug_buf, debug_len, task); debug_ptr = debug_buf; debug_len = 0; } vtstrcpy(debug_ptr, line); debug_ptr += vtstrlen(line); debug_len += vtstrlen(line);#else stat = db_trace_write(trace_fd, line, vtstrlen(line), task);#endif if (stat != 0) return FALSE; if (pos) {#ifdef MEM_DEBUG if (debug_len >= DEBUG_BUFLEN - 3) { if (!trace_fd) { trace_fd = psp_fileOpen(name, O_WRONLY | O_CREAT, PSP_FLAG_DENYNO); } if (trace_fd) stat = db_trace_write(trace_fd, debug_buf, debug_len, task); debug_ptr = debug_buf; debug_len = 0; } vtstrcpy(debug_ptr, DB_TEXT("\r\n")); debug_ptr += 2; debug_len += 2;#else stat = db_trace_write(trace_fd, DB_TEXT("\r\n"), 2, task);#endif if (stat < 0) return FALSE; line = ++pos; } } while (pos && *pos); va_end(args); #ifndef MEM_DEBUG if (task->dboptions & SYNCFILES) psp_fileSync(trace_fd); last_len = psp_fileLength(trace_fd); psp_fileSeek(trace_fd, 0L); psp_fileUnlock(trace_fd);#endif /* MEM_DEBUG */ } psp_syncExitExcl(debug_mutex); return TRUE;}int INTERNAL_FCN db_indent(DB_TASK *task){ return ++task->db_indent;}int INTERNAL_FCN db_undent(DB_TASK *task){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?