layout bug due to failure to call layout.

Sqlite3 crash due to premature call to shutdown.

calls to layout very rarely have any obvious effect,
but sometimes under odd and idiosyncratic circumstances
they do.

Called shutdown after the destroy was executed, but destroy does
not immediately destroy the windows, thus does not immediately
finalize all compiled sql statements and close all database
connections. You have to wait for all the windows to be destroyed.
Again, a rare crash except under certain special circumstances.
This commit is contained in:
Cheng 2023-11-12 09:43:19 +00:00
parent c65f2fbf6e
commit 224ab60395
No known key found for this signature in database
GPG Key ID: 571C3A9C3B9E6FCA
4 changed files with 18 additions and 8 deletions

View File

@ -31,9 +31,10 @@
class Icompiled_sql
{
protected:
Icompiled_sql() = default; // needed for derived constructor
Icompiled_sql() {} //Has to exist, because derived objects will exist and need to create their base class
public:
virtual ~Icompiled_sql() = default; // needed for derived destructor
virtual ~Icompiled_sql() {
} //Has to exist, because derived objects will exist and need to destroy their base class
// Bind is used when writing stuff into the database. These objects should continue to exist until the write is finalized or reset.
virtual void Isqlite3_bind( int, const std::span<const uint8_t>) = 0; // https://sqlite.org/c3ref/bind.html
virtual void Isqlite3_bind(int, int) = 0;
@ -69,18 +70,22 @@ class ISqlite3
protected:
ISqlite3() = default; // needed for derived constructor
public:
virtual ~ISqlite3() = default; // needed for derived destructor
virtual ~ISqlite3() {
}; // needed for derived destructor
virtual void exec(const char*) = 0;
};
// Factory method to open a database and produce a shared object wrapping the database
ISqlite3* Sqlite3_open(const char*);
ISqlite3* Sqlite3_open(const char*); //The actual run time object is the derived class
//Which lives a symbol space that is kept separate from wxWidgets C++ space
// Factory method to create a database and produce a shared object wrapping the database
ISqlite3* Sqlite3_create(const char*);
ISqlite3* Sqlite3_create(const char*);//The actual run time object is the derived class
//Which lives a symbol space that is kept separate from wxWidgets C++ space
// Factory method to prepare a compiled sql statement
Icompiled_sql* sqlite3_prepare(ISqlite3*, const char *);
Icompiled_sql* sqlite3_prepare(ISqlite3*, const char *);//The actual run time object is the derived class
//Which lives a symbol space that is kept separate from wxWidgets C++ space
void sqlite3_init();
extern "C" {

View File

@ -197,5 +197,6 @@ void App::OnError(wxCommandEvent& event)
int App::OnExit()
{ if (errorCode)wxLogDebug("%s", szError);
m_Config.Flush();
sqlite3_shutdown();
return 0;
}

View File

@ -81,6 +81,10 @@ struct display_wallet::cleanup {
assert(sizer);
}
~cleanup() {
sizer->Layout();
// most of the time the layout command has no effect, but it has effect
// if adding a name longer than any of the existing names
// as when one adds the first name.
auto desired_size = sizer->ComputeFittingClientSize(singletonFrame);
dirty_area.IncTo(desired_size);
//singletonFrame->SetMinClientSize(desired_size);

View File

@ -305,7 +305,6 @@ void Frame::OnClose(wxCloseEvent& event) {
// This event gives you the opportunity to clean up anything that needs explicit cleanup, albeit if you have done your work right nothing should need explicit cleanup,
// and to object to the closing in a "file not saved" type situation.
// https://docs.wxwidgets.org/trunk/classwx_close_event.html
if (sqlite3_shutdown())wxMessageBox(wxT(R"|(Sqlite3 shutdown error)|"), wsz_error, wxICON_ERROR);
DestroyChildren();
Destroy(); //Default handler will destroy the window. This is our handler for the user calling close, replacing the default handler.
}
@ -580,4 +579,5 @@ Frame::~Frame() {
wxMenuTracker::check_dynamic_menus_absent();
}
singletonFrame = nullptr;
if (sqlite3_shutdown())wxMessageBox(wxT(R"|(Sqlite3 shutdown error)|"), wsz_error, wxICON_ERROR);
}