Skip to content

Commit

Permalink
Fix crash when exporting peak CSV on wxWidgets build.
Browse files Browse the repository at this point in the history
`Wt::WServer::instance()` will return nullptr if called from a different
runtime, which was the case for the wxWidgets build in
InterSpecWebFrame.cpp, when the app was built with batch mode, so that
LibInterSpec is shared (and static runtime used to compile, on Windows).
So now get this instance from `InterSpecServer` located within
LibInterSpec.
Tried to improve the 2compile warnings caused by boost::bind, a litte.
  • Loading branch information
wcjohns committed Sep 14, 2024
1 parent 6f258bb commit 96bdcc2
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 9 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ target_compile_options(InterSpecLib PRIVATE

# Turn off "note: The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated...."
# warnings (these come from Wt I think, not our code)
target_compile_definitions(InterSpecLib PUBLIC -D BOOST_BIND_GLOBAL_PLACEHOLDERS)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D BOOST_BIND_GLOBAL_PLACEHOLDERS")

if(WIN32)
#0x0601==Win7, 0x0501=WinXP (Wt CMakeLists.txt uses 0x0501x)
Expand Down
12 changes: 12 additions & 0 deletions InterSpec/InterSpecServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

#include <Wt/WApplication>

namespace Wt
{
class WServer;
}

namespace InterSpecServer
{
Expand Down Expand Up @@ -108,6 +112,14 @@ namespace InterSpecServer
// Example value returned: "http://127.0.0.1:7234"
InterSpec_API std::string urlBeingServedOn();

/** Returns the Wt::WServer created by `startServer(...)`.
If we are linking against LibInterSpec dynamically, and using the static
runtime on Windows (default build option), we cant call
`Wt::WServer::instance()`, since its in a different runtime, and we'll
get nullptr back, so instead we need to call this function
*/
InterSpec_API Wt::WServer *get_wt_server();

InterSpec_API bool changeToBaseDir( int argc, char *argv[] );

Expand Down
5 changes: 0 additions & 5 deletions InterSpec/InterSpec_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,6 @@ void log_developer_error( const char *location, const char *error );
#define DATE_TIME_FORMAT_STR "d-MMM-yyyy hh:mm:ss"


// Prevent some compile warnings from using like _1 instead of
// boost::placeholders::_1 (I think this must be in the Wt
// headers, since our code uses the namespace prefixes)
#define BOOST_BIND_GLOBAL_PLACEHOLDERS

#define InterSpec_PHONE_ROTATE_FOR_TABS 1

// On Windows, we will compile LibInterSpec as a shared DLL only when
Expand Down
5 changes: 3 additions & 2 deletions src/AppUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "InterSpec_config.h"

#include <string>
#include <fstream>
#include <iostream>
#include <stdexcept>

Expand Down Expand Up @@ -381,9 +382,9 @@ std::string file_contents( const std::string &filename )
//Copied from SpecUtils::load_file_data( const char * const filename, std::vector<char> &data );
#ifdef _WIN32
const std::wstring wfilename = SpecUtils::convert_from_utf8_to_utf16(filename);
basic_ifstream<char> stream(wfilename.c_str(), ios::binary);
std::ifstream stream(wfilename.c_str(), ios::binary);
#else
basic_ifstream<char> stream(filename.c_str(), ios::binary);
std::ifstream stream(filename.c_str(), ios::binary);
#endif

if (!stream)
Expand Down
7 changes: 7 additions & 0 deletions src/InterSpecServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ namespace InterSpecServer
std::lock_guard<std::mutex> lock( sm_servedOnMutex );
return sm_urlServedOn;
}


Wt::WServer *get_wt_server()
{
std::lock_guard<std::mutex> serverlock( ns_servermutex );
return ns_server;
}


std::string getWtConfigXml( int argc, char *argv[] )
Expand Down
3 changes: 3 additions & 0 deletions target/batch/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ target_link_libraries( InterSpec_batch PUBLIC InterSpecLib )
set_target_properties( InterSpec_batch PROPERTIES CXX_STANDARD 14 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO )
set_target_properties( InterSpec_batch PROPERTIES OUTPUT_NAME "InterSpec_batch" )

# Turn off "note: The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated...."
# warnings (these come from Wt I think, not our code)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D BOOST_BIND_GLOBAL_PLACEHOLDERS")

if(WIN32)
# Allow using wildcards from the command-line on Windows.
Expand Down
3 changes: 3 additions & 0 deletions target/wxWidgets/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_JS_LIB} InterSpecLib )
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO )
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "InterSpec")

# Turn off "note: The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated...."
# warnings (these come from Wt I think, not our code)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D BOOST_BIND_GLOBAL_PLACEHOLDERS")

set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true)

Expand Down
6 changes: 5 additions & 1 deletion target/wxWidgets/InterSpecWebFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,11 @@ void InterSpecWebFrame::OnNewWindow(wxWebViewEvent& evt)
//CSV, spectrum file, JSON file, etc
wxLogMessage("%s", "File to save; url='" + evt.GetURL() + "', target='" + evt.GetTarget() + "'");

auto server = Wt::WServer::instance();
// If we are linking against LibInterSpec dynamically, and using the static runtime on Windows
// (default build option), we cant call `Wt::WServer::instance()`, since its in a different
// runtime, and we'll get nullptr back.
Wt::WServer *server = InterSpecServer::get_wt_server();

assert(server);
Wt::Http::Client* client = new Wt::Http::Client( server->ioService() );
client->setTimeout(10);
Expand Down

0 comments on commit 96bdcc2

Please sign in to comment.