blob: f07443c7e9472e84af506a722d14acb9b5af2505 [file]
/* $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;
}