| /* $Id$ | |
| * | |
| * Licensed to the Apache Software Foundation (ASF) under one or more | |
| * contributor license agreements. See the NOTICE file distributed with | |
| * this work for additional information regarding copyright ownership. | |
| * The ASF licenses this file to you under the Apache License, Version | |
| * 2.0 (the "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| /** | |
| * etch_global.c -- logically global methods, "static" methods, etc. | |
| * methods which can logically be executed from any context. | |
| */ | |
| #include <stdio.h> | |
| #ifdef WIN32 | |
| #include <windows.h> | |
| #endif | |
| #include "etch_global.h" | |
| #include "etchlog.h" | |
| #include "etchutl.h" | |
| #include <conio.h> | |
| wchar_t* etch_emptystru = L""; | |
| char* etch_emptystra = ""; | |
| char* ETCHGLOB = "ETCH"; | |
| void etch_instantiate_global_constants(); | |
| void etch_free_global_constants(); | |
| /** | |
| * etch_runtime_init() | |
| * global etch runtime startup initialization. | |
| */ | |
| int etch_runtime_init(const int is_client) | |
| { | |
| int result = 0; | |
| if (is_runtime_initialized) return 1; | |
| etchlog_open(is_client); /* open log file */ | |
| etch_read_configfile(is_client, TRUE); /* initialize config - read config file */ | |
| etchlog(ETCHGLOB, ETCHLOG_INFO, "log priority level is '%c'\n", config.log_level); | |
| etch_instantiate_global_constants(); /* initialize quasi-static constants */ | |
| #if IS_TRACKING_ETCHHEAP /* warning re memory tracking overhead */ | |
| etchlog(ETCHGLOB, ETCHLOG_WARNING, "IS_TRACKING_ETCHHEAP is ON (normally off)\n"); | |
| /* etch_watch_id is the global allocator ordinal for memory leak analysis. | |
| * if etch_watch_id is nonzero, and if IS_TRACKING_ETCHHEAP is compiled TRUE, | |
| * a debug break will occur at the specified memory allocation ordinal. | |
| */ | |
| etch_watch_id = config.memory_watch_id; | |
| if (etch_watch_id) | |
| etchlog(ETCHGLOB, ETCHLOG_WARNING, | |
| "memory watch ID found - break to debugger may occur\n"); | |
| #endif | |
| #if(0) | |
| #if IS_USING_ALLOC_ID | |
| etchlog(ETCHGLOB, ETCHLOG_INFO, "IS_USING_ALLOC_ID is compiled ON (normally off)\n"); | |
| #endif | |
| #endif | |
| is_runtime_initialized = TRUE; | |
| result = cache_create()? 0: -1; /* instantiate runtime cache */ | |
| if (0 == result) /* initialize running count of log files */ | |
| etchlog_set_logfile_count (etchlog_countfiles (etchlog_get_dirpath())); | |
| return result; | |
| } | |
| /** | |
| * etch_runtime_cleanup() | |
| * global etch runtime cleanup | |
| * clears and frees the memory tracking table, and finally the runtime cache | |
| */ | |
| int etch_runtime_cleanup(int n, int m) | |
| { | |
| is_memtable_instance = TRUE; | |
| etch_free_global_constants(); | |
| destroy_hashtable(memtable, TRUE, TRUE); | |
| memtable = NULL; | |
| is_memtable_instance = FALSE; | |
| cache_destroy(); | |
| return 0; | |
| } | |
| /** | |
| * memtable_clear() | |
| * global memory tracking table checkpoint. | |
| * clears all entries from the memory tracking table but leaves table intact. | |
| * we would use this for example between unit tests which uncovered memory leaks, | |
| * but we did not want to carry forward the leaks to the next tests. | |
| */ | |
| int memtable_clear() | |
| { | |
| etchheap_currbytes = 0; | |
| if (NULL == memtable) return 0; | |
| is_memtable_instance = TRUE; | |
| memtable->vtab->clear(memtable->realtable, TRUE, TRUE, memtable, 0); | |
| is_memtable_instance = FALSE; | |
| return 0; | |
| } | |
| /** | |
| * etch_strbytes() | |
| * @param s a unicode string. | |
| * @return number of bytes in s | |
| */ | |
| size_t etch_strbytes(const wchar_t* s) | |
| { | |
| return s? (wcslen(s) + 1) * sizeof(wchar_t): 0; | |
| } | |
| /** | |
| * etch_instantiate_global_constants() | |
| * instantiate global constants. these are constants which can't be statically intialized. | |
| * some of these may need to be freed in etch_free_global_constants in order that tests | |
| * can show all memory freed. any etch objects instantiated here may need to have their | |
| * is_static marker set in order that they remain instantiated throughout execution. | |
| */ | |
| void etch_instantiate_global_constants() | |
| { | |
| etchgc.etch_charsetname_us_ascii = L"us-ascii"; | |
| etchgc.etch_charsetname_utf8 = L"utf-8"; | |
| etchgc.etch_charsetname_utf16 = L"utf-16"; | |
| etchgc.pctd = "%d"; | |
| } | |
| /** | |
| * etch_free_global_constants() | |
| * free memory for global constants. etch objects freed here may need to have their | |
| * is_static marker reset to zero so that their destructors will free them. | |
| */ | |
| void etch_free_global_constants() | |
| { | |
| } | |
| /** | |
| * get_dynamic_classid() | |
| * get a class ID for objects not known to the binding. | |
| * assignment is currently non-atomic. | |
| */ | |
| unsigned short get_dynamic_classid() | |
| { | |
| if (g_etch_curr_classid == 0) | |
| g_etch_curr_classid = CLASSID_DYNAMIC_START; | |
| return g_etch_curr_classid++; | |
| } | |
| /** | |
| * get_dynamic_classid_unique() | |
| * if specified ID already assigned, return it; otherwise generate and return. | |
| * assignment is currently non-atomic. | |
| */ | |
| unsigned short get_dynamic_classid_unique(unsigned short* globalid) | |
| { | |
| if (*globalid == 0) | |
| *globalid = get_dynamic_classid(); | |
| return (*globalid); | |
| } | |
| /** | |
| * is_bad_pointer() | |
| * not sure how portable this is, but it catches freed windows heap content | |
| * such as pointer values 0xcccccccc, 0xfeeefeee, etc. it judges the specified | |
| * pointer to be bad if the high nibble is non-zero. | |
| */ | |
| boolean is_bad_pointer(void* p) | |
| { | |
| const static size_t mask = 0xf << (((sizeof(void*) - 1) * 8) + 4); | |
| return ((size_t)p & mask) != 0; | |
| } | |
| /** | |
| * waitkey() | |
| * method to wait for a keypress. called from client and server exe's in order | |
| * to optionally not exit console window until a key is pressed. | |
| */ | |
| int waitkey(const int is_waitkey_enabled, const int result) | |
| { | |
| if (is_waitkey_enabled) | |
| { printf("any key ..."); | |
| while(!_getch()); | |
| printf("\n"); | |
| } | |
| return result; | |
| } | |
| /** | |
| * etch_system_nanotime() | |
| * operating system specific implementation of java System.nanotime(). | |
| */ | |
| int64 etch_system_nanotime() | |
| { | |
| int64 result = 0; | |
| #ifdef WIN32 | |
| LARGE_INTEGER li; | |
| QueryPerformanceCounter(&li); | |
| result = li.QuadPart; | |
| #endif /* WIN32 */ | |
| return result; | |
| } | |