add gb_json life monitor; fix mem-leak when update_data
This commit is contained in:
parent
d5b90ef03b
commit
02abb23198
|
@ -956,7 +956,7 @@ scanner_err hg_scanner_mgr::hg_scanner_get_parameter(scanner_handle h, const cha
|
|||
device_option* tmp = nullptr;
|
||||
if (!h)
|
||||
{
|
||||
device_option* tmp = new device_option();
|
||||
tmp = new device_option();
|
||||
|
||||
tmp->add(offline_);
|
||||
tmp->add(g_language);
|
||||
|
|
|
@ -420,6 +420,8 @@ extern "C"
|
|||
|
||||
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
//static _CrtMemState state;
|
||||
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
//if (g_scanner_path.empty())
|
||||
|
@ -433,6 +435,9 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
|
|||
// g_scanner_path = path;
|
||||
// }
|
||||
//}
|
||||
#ifdef _DEBUG
|
||||
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||
#endif
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -119,3 +119,85 @@ extern "C" { // avoid compiler exporting name in C++ style !!!
|
|||
}
|
||||
|
||||
|
||||
|
||||
#if defined(WIN32) || defined(_WIN64)
|
||||
|
||||
#include <json/gb_json.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
typedef struct _jsn_obj
|
||||
{
|
||||
gb_json* jsn;
|
||||
int from;
|
||||
|
||||
bool operator==(const gb_json* obj)
|
||||
{
|
||||
return jsn == obj;
|
||||
}
|
||||
}JSNOBJ;
|
||||
static std::vector<JSNOBJ> g_jsn_objs;
|
||||
static int max_objs = 0;
|
||||
static void record_json(gb_json* jsn, bool add, void* param)
|
||||
{
|
||||
std::vector<JSNOBJ>::iterator it = std::find(g_jsn_objs.begin(), g_jsn_objs.end(), jsn);
|
||||
if (it == g_jsn_objs.end())
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
JSNOBJ jo;
|
||||
DWORD base = 0;
|
||||
|
||||
_asm
|
||||
{
|
||||
push eax
|
||||
mov eax, ebp
|
||||
mov base, eax
|
||||
pop eax
|
||||
}
|
||||
jo.jsn = jsn;
|
||||
jo.from = ((DWORD***)base)[0][0][1];
|
||||
g_jsn_objs.push_back(jo);
|
||||
if (max_objs < g_jsn_objs.size())
|
||||
max_objs = g_jsn_objs.size();
|
||||
}
|
||||
}
|
||||
else if (!add)
|
||||
g_jsn_objs.erase(it);
|
||||
}
|
||||
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
//static _CrtMemState state;
|
||||
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
//if (g_scanner_path.empty())
|
||||
//{
|
||||
// char path[MAX_PATH] = { 0 };
|
||||
|
||||
// GetModuleFileNameA(inst, path, _countof(path) - 1);
|
||||
//// if (strrchr(path, '\\'))
|
||||
// {
|
||||
//// strrchr(path, '\\')[1] = 0;
|
||||
// g_scanner_path = path;
|
||||
// }
|
||||
//}
|
||||
//_CrtMemCheckpoint(&state);
|
||||
#ifdef _DEBUG
|
||||
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||
_CrtSetBreakAlloc(632555577);
|
||||
set_gbjson_life_callback(record_json, nullptr);
|
||||
#endif
|
||||
}
|
||||
else if (reason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
_CrtDumpMemoryLeaks();
|
||||
#endif
|
||||
//_CrtMemDumpAllObjectsSince(&state);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#include "gb_json.h"
|
||||
|
||||
#include "cJSON.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -82,31 +82,79 @@ namespace special_char_trans
|
|||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// life callback ...
|
||||
#ifdef DUMP_JSON_OBJECT_LIFE
|
||||
static void record_life_empty(gb_json*, bool, void*)
|
||||
{}
|
||||
static void(*g_life)(gb_json*, bool, void*) = &record_life_empty;
|
||||
static void* g_life_param = nullptr;
|
||||
|
||||
void set_gbjson_life_callback(void(*life)(gb_json*, bool, void*), void* param)
|
||||
{
|
||||
g_life_param = param;
|
||||
g_life = life ? life : &record_life_empty;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// gb_json ...
|
||||
gb_json::gb_json(char* json_txt) : ref_(1), type_(VAL_TYPE_OBJECT), key_(""), strval_(""), cur_child_(-1)
|
||||
{
|
||||
#ifdef DUMP_JSON_OBJECT_LIFE
|
||||
g_life(this, true, g_life_param);
|
||||
#endif
|
||||
|
||||
simple_val_.dval = .0f;
|
||||
if(json_txt)
|
||||
attach_text(json_txt);
|
||||
}
|
||||
gb_json::gb_json(const char* key, bool val) : ref_(1), type_(VAL_TYPE_BOOL), key_(key ? key : ""), strval_(""), cur_child_(-1)
|
||||
{
|
||||
#ifdef DUMP_JSON_OBJECT_LIFE
|
||||
g_life(this, true, g_life_param);
|
||||
#endif
|
||||
|
||||
simple_val_.bval = val;
|
||||
}
|
||||
gb_json::gb_json(const char* key, int val) : ref_(1), type_(VAL_TYPE_INT), key_(key ? key : ""), strval_(""), cur_child_(-1)
|
||||
{
|
||||
#ifdef DUMP_JSON_OBJECT_LIFE
|
||||
g_life(this, true, g_life_param);
|
||||
#endif
|
||||
|
||||
simple_val_.nval = val;
|
||||
}
|
||||
gb_json::gb_json(const char* key, double val) : ref_(1), type_(VAL_TYPE_FLOAT), key_(key ? key : ""), strval_(""), cur_child_(-1)
|
||||
{
|
||||
#ifdef DUMP_JSON_OBJECT_LIFE
|
||||
g_life(this, true, g_life_param);
|
||||
#endif
|
||||
|
||||
simple_val_.dval = val;
|
||||
}
|
||||
gb_json::gb_json(const char* key, const char* val) : ref_(1), type_(VAL_TYPE_STRING), key_(key ? key : ""), strval_(val ? val : ""), cur_child_(-1)
|
||||
{}
|
||||
{
|
||||
#ifdef DUMP_JSON_OBJECT_LIFE
|
||||
g_life(this, true, g_life_param);
|
||||
#endif
|
||||
}
|
||||
gb_json::gb_json(const char* key, const std::string& val) : ref_(1), type_(VAL_TYPE_STRING), key_(key ? key : ""), strval_(val), cur_child_(-1)
|
||||
{}
|
||||
{
|
||||
#ifdef DUMP_JSON_OBJECT_LIFE
|
||||
g_life(this, true, g_life_param);
|
||||
#endif
|
||||
}
|
||||
gb_json::~gb_json()
|
||||
{
|
||||
clear();
|
||||
#ifdef DUMP_JSON_OBJECT_LIFE
|
||||
g_life(this, false, g_life_param);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string gb_json::object_key(gb_json* jsn)
|
||||
|
|
|
@ -116,3 +116,7 @@ public:
|
|||
bool operator==(const gb_json& r);
|
||||
bool operator!=(const gb_json& r);
|
||||
};
|
||||
|
||||
#ifdef DUMP_JSON_OBJECT_LIFE
|
||||
void set_gbjson_life_callback(void(*life)(gb_json*, bool, void*), void* param);
|
||||
#endif
|
|
@ -1687,10 +1687,8 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne
|
|||
{
|
||||
bool ro = false;
|
||||
if ((child->get_value("readonly", ro) && ro)
|
||||
|| (child->get_value("auth", err) && !user_(err)))
|
||||
|| (child->get_value("auth", err) && user_ && !user_(err)))
|
||||
{
|
||||
child->release();
|
||||
|
||||
err = SCANNER_ERR_ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
|
@ -1718,7 +1716,8 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne
|
|||
}
|
||||
|
||||
if (err == SCANNER_ERR_OK || err == SCANNER_ERR_NOT_EXACT
|
||||
|| err == SCANNER_ERR_RELOAD_IMAGE_PARAM || err == SCANNER_ERR_RELOAD_OPT_PARAM)
|
||||
|| err == SCANNER_ERR_RELOAD_IMAGE_PARAM || err == SCANNER_ERR_RELOAD_OPT_PARAM
|
||||
|| err == SCANNER_ERR_CONFIGURATION_CHANGED)
|
||||
{
|
||||
child->get_value("type", type);
|
||||
if (type == JSON_SANE_TYPE_BOOL)
|
||||
|
@ -1741,7 +1740,6 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne
|
|||
child->set_value("cur", (char*)value);
|
||||
changed = pre != (char*)value;
|
||||
}
|
||||
child->release();
|
||||
|
||||
// set paper-w and paper-h
|
||||
if (strcmp(name, SANE_STD_OPT_NAME_PAPER) == 0 ||
|
||||
|
@ -1750,19 +1748,20 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne
|
|||
if (src_.count(SANE_STD_OPT_NAME_PAPER_W))
|
||||
{
|
||||
std::string w(src_[SANE_STD_OPT_NAME_PAPER_W]->get_value(SANE_STD_OPT_NAME_PAPER_W, nullptr)),
|
||||
h(src_[SANE_STD_OPT_NAME_PAPER_H]->get_value(SANE_STD_OPT_NAME_PAPER_H, nullptr)),
|
||||
lateral(get_option_value(SANE_STD_OPT_NAME_LATERAL, SANE_ACTION_GET_VALUE));
|
||||
h(src_[SANE_STD_OPT_NAME_PAPER_H]->get_value(SANE_STD_OPT_NAME_PAPER_H, nullptr)),
|
||||
lateral(get_option_value(SANE_STD_OPT_NAME_LATERAL, SANE_ACTION_GET_VALUE));
|
||||
gb_json *jsnl = nullptr;
|
||||
|
||||
now_->get_value(SANE_STD_OPT_NAME_LATERAL, child);
|
||||
if (child)
|
||||
now_->get_value(SANE_STD_OPT_NAME_LATERAL, jsnl);
|
||||
if (jsnl)
|
||||
{
|
||||
if (device_option::is_opt_enabled(child, nullptr, nullptr, nullptr))
|
||||
if (device_option::is_opt_enabled(jsnl, nullptr, nullptr, nullptr))
|
||||
{
|
||||
refine_data(SANE_STD_OPT_NAME_LATERAL, &lateral[0]);
|
||||
if (*(bool*)&lateral[0])
|
||||
w.swap(h);
|
||||
}
|
||||
child->release();
|
||||
jsnl->release();
|
||||
}
|
||||
|
||||
gb_json* pw = nullptr,
|
||||
|
@ -1798,6 +1797,9 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne
|
|||
}
|
||||
} // provider has processed right
|
||||
} // not read-only option
|
||||
|
||||
child->release();
|
||||
|
||||
} // has option named 'name'
|
||||
} // has initialized
|
||||
|
||||
|
|
Loading…
Reference in New Issue