I'm implementing fluid simulator using PhysiX. Unfortunately sth is wrong with cuda context manager and I have a problem with recognizing what it is. I have an init method which looks like this:
void InitializePhysX() {
bool recordMemoryAllocations = true;
const bool useCustomTrackingAllocator = true;
PxAllocatorCallback* allocator = &gDefaultAllocatorCallback;
PxErrorCallback* error = &gDefaultErrorCallback;
PxFoundation* mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, *allocator, *error);
if(!mFoundation)
printf("PxCreateFoundation failed!\n");
PxProfileZoneManager* mProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(mFoundation);
if(!mProfileZoneManager)
printf("PxProfileZoneManager::createProfileZoneManager failed!\n");
#ifdef PX_WINDOWS
pxtask::CudaContextManagerDesc cudaContextManagerDesc;
pxtask::CudaContextManager* mCudaContextManager = pxtask::createCudaContextManager(*mFoundation, cudaContextManagerDesc, mProfileZoneManager);
if( mCudaContextManager ){
if( !mCudaContextManager->contextIsValid() ){
mCudaContextManager->release();
mCudaContextManager = NULL;
printf("invalid context\n");
}
} else {
printf("create cuda context manager failed\n");
}
#endif
mPhysX = PxCreatePhysics(PX_PHYSICS_VERSION, *mFoundation, PxTolerancesScale(), recordMemoryAllocations, mProfileZoneManager);
if(!mPhysX)
printf("PxCreatePhysics failed!\n");
...
}
When I try to run my application it occures that mCudaContextManger is never created properly. "create cuda context manager failed" is being wrote on the console and:
"....\LowLevel\software\src\PxsContext.cpp (1122) : warning : GPU operation faied. No px::CudaContextManager available.
....\SimulationController\src\particles\ScParticleSystemSim.cpp (73) : warning : GPU particle system creation failed. Falling back to CPU implementation."
I have GeForce560Ti with newest driver (error also shows up on GeForce460 on my friend's laptop). Physix is set to use GPU in NVidia Control Panel.
Does anybody know what we made wrong and how to make GPU work? Thanks in advance!
File PhysX3Gpu_x86.dll was missing. I added it and now everything is fine.
Related
I am trying to set properties of captured image in linux.
For example:
format, width, height, that could be achieved by:
VIDIOC_S_FMT/VIDIOC_G_FMT + struct v4l2_format fmt;
But, I am blocked in getting/setting more detail parameters:
like H264 key-frame period.
I found there are api to reach the goal.
that are v4l2_ext_controls, v4l2-ext-control and VIDIOC_G_EXT_CTRLS.
I have tried that, but that did not work in my example code.
My code is like this :
struct v4l2_ext_control extCtrl;
memset(&extCtrl, 0, sizeof(struct v4l2_ext_control));
extCtrl.id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD;
extCtrl.size = 0;
extCtrl.value = 2;
struct v4l2_ext_controls extCtrls;
extCtrls.controls = &extCtrl;
extCtrls.count = 1;
extCtrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, &extCtrls);
if (0 < ret)
{
printf("VIDIOC_S_EXT_CTRLS setting (%s)\n", strerror(errno));
return -3;
}/*if*/
ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, &extCtrls);
if (0 < ret)
{
printf("VIDIOC_G_EXT_CTRLS setting (%s)\n", strerror(errno));
return -4;
}/*if*/
printf("extCtrl.value = %d\n", extCtrl.value );
That seems well, the key frame period be 2 (extCtrl.value).
But when I used
ffplay -skip_frame nokey -i saved_raw_h264
The key frame period is obviously much greater than 2.
May anyone help me?
By the way: The Logitech C920, is the only one camera I know, supports h264 output in consumer market.
Does any know other camera supporting h264?
Assuming you are setting the parameters correctly, it's very possible that the Logitech C920 Linux driver is ignoring some, if not many, of the control parameters you are passing in via V4L2. Do you have the driver source for the C920? Or is it using a generic Linux USB camera driver? You could at least see which V4L2 controls are supported by the driver.
edit:
Have you seen these threads which talk about adding C920 support to gstreamer?
http://sourceforge.net/p/linux-uvc/mailman/linux-uvc-devel/thread/505D0DAE.7020907#collabora.co.uk/
http://kakaroto.homelinux.net/2012/09/uvc-h264-encoding-cameras-support-in-gstreamer/
In Windows Store Apps, C++(C# is similar though), doing something like
IAsyncAction^ Action = CurrentAppSimulator::ReloadSimulatorAsync(proxyFile);
create_task( Action ).then([this]()
{
}.wait();
results in an unhandled exception. Usually it's
Microsoft C++ exception: Concurrency::invalid_operation at memory location 0x0531eb58
And I kind of need for that action to finish to get my In App Purchase information before trying to use it.
The weird thing here is that anything else besides IAsyncAction waits just fine. IAsyncOperation and IAsyncOperationWithProgress worked just fine, but this ? Exception and then crash.
To be honest, I have no idea what's the difference between an IAsyncOperation and an IAsyncAction, they seem similar to me.
UPDATE :
By analyzing this page http://msdn.microsoft.com/en-us/library/vstudio/hh750082.aspx you can figure out that IAsyncAction is just an IAsyncOperation without a return type. But, you can then see that most IAsyncAction-s are waitable. The real problem though is that certain Windows functions just want to execute on a particular thread (for some reason). ReloadSimulatorAsync is one such fine example.
Using code like this :
void WaitForAsync( IAsyncAction ^A )
{
while(A->Status == AsyncStatus::Started)
{
std::chrono::milliseconds milis( 1 );
std::this_thread::sleep_for( milis );
}
AsyncStatus S = A->Status;
}
results in an infinite loop. If called upon other functions it actually works. The problem here is why does a task need to be executed on a particular thread if everything is Async ? Instead of Async it should be RunOn(Main/UI)Thread or similar.
SOLVED, see answer;
Calling wait on the concurrency::task after you create it completely defeats the point of having tasks in the first place.
What you have to realize is that in the Windows Runtime, there are many asynchronous operations that cannot (or should not) be run on (or waited for on) the UI thread; you've found one of them, and now you're trying to wait on it. Instead of potentially causing a deadlock, you're getting an exception.
To remedy this, you need to use a continuation. You're most of the way there; you're already defining a continuation function:
IAsyncAction^ Action = CurrentAppSimulator::ReloadSimulatorAsync(proxyFile);
create_task( Action ).then([this]()
{
}).wait();
// do important things once the simulator has reloaded
important_things();
...but you're not using it. The purpose of the function you pass into then is to be called off the UI thread once the task is complete. So, instead, you should do this:
IAsyncAction^ Action = CurrentAppSimulator::ReloadSimulatorAsync(proxyFile);
create_task( Action ).then([this]()
{
// do important things once the simulator has reloaded
important_things();
});
Your important post-reload code won't run until the task is complete, and it will run on a background thread so it doesn't block or deadlock the UI.
This is the magical fix that gets the job done :
void WaitForAsync( IAsyncAction ^A )
{
while(A->Status == Windows::Foundation::AsyncStatus::Started)
{
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
}
Windows::Foundation::AsyncStatus S = A->Status;
}
In general you should use the continuations (.then(...)), like Adam's answer says, and not block. But lets say you want to do a wait for some reason (for testing some code?), you can trigger an event from the last continuation (to use C# parlance):
TEST_METHOD(AsyncOnThreadPoolUsingEvent)
{
std::shared_ptr<Concurrency::event> _completed = std::make_shared<Concurrency::event>();
int i;
auto workItem = ref new WorkItemHandler(
[_completed, &i](Windows::Foundation::IAsyncAction^ workItem)
{
Windows::Storage::StorageFolder^ _picturesLibrary = Windows::Storage::KnownFolders::PicturesLibrary;
Concurrency::task<Windows::Storage::StorageFile^> _getFileObjectTask(_picturesLibrary->GetFileAsync(L"art.bmp"));
auto _task2 = _getFileObjectTask.then([_completed, &i](Windows::Storage::StorageFile^ file)
{
i = 90210;
_completed->set();
});
});
auto asyncAction = ThreadPool::RunAsync(workItem);
_completed->wait();
int j = i;
}
By the way, for some reason this method causes an exception when after it is over in visual studio tests. I've tested it in an app too though and it worked with no problem. I'm not quite sure what the problem is with the test.
If anybody wants a C++/Wrl example then I have that too.
Update 07/08/2017: As requested here is a C++/Wrl example. I have just run this in a Universal Windows (10) Test project in Visual Studio 2017. The key thing here is the weird part Callback<Implements< RuntimeClassFlags<ClassicCom >, IWorkItemHandler , FtmBase >> , as opposed to just Callback<IWorkItemHandler> . When I had the latter, the program jammmed except for when it was in a .exe project. I found this solution here: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/ef6f84f6-ad4d-44f0-a107-3922d56662e6/thread-pool-task-blocking-ui-thread . See "agile objects" for more information.
#include "pch.h"
#include "CppUnitTest.h"
#include <Windows.Foundation.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <wrl/event.h>
#include <memory>
#include "concrt.h"
#include <Windows.System.Threading.h>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace Windows::System::Threading;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::System::Threading;
namespace TestWinRtAsync10
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(AsyncOnThreadPoolUsingEvent10Wrl)
{
HRESULT hr = BasicThreadpoolTestWithAgileCallback();
Assert::AreEqual(hr, S_OK);
}
HRESULT BasicThreadpoolTestWithAgileCallback()
{
std::shared_ptr<Concurrency::event> _completed = std::make_shared<Concurrency::event>();
ComPtr<ABI::Windows::System::Threading::IThreadPoolStatics> _threadPool;
HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_System_Threading_ThreadPool).Get(), &_threadPool);
ComPtr<IAsyncAction> asyncAction;
hr = _threadPool->RunAsync(Callback<Implements<RuntimeClassFlags<ClassicCom>, IWorkItemHandler, FtmBase>>([&_completed](IAsyncAction* asyncAction) -> HRESULT
{
// Prints a message in debug run of this test
std::ostringstream ss;
ss << "Threadpool work item running.\n";
std::string _string = ss.str();
std::wstring stemp = std::wstring(_string.begin(), _string.end());
OutputDebugString(stemp.c_str());
//
_completed->set();
return S_OK;
}).Get(), &asyncAction);
_completed->wait();
return S_OK;
}
};
}
Update 08/08/2017: More example, per the comments.
#include "pch.h"
#include "CppUnitTest.h"
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <wrl/event.h>
#include <memory>
#include "concrt.h"
#include <Windows.System.Threading.h>
#include <Windows.ApplicationModel.Core.h>
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
namespace TestWinRtAsync10
{
TEST_CLASS(TestWinRtAsync_WrlAsyncTesting)
{
public:
TEST_METHOD(PackageClassTest)
{
ComPtr<ABI::Windows::ApplicationModel::IPackageStatics> _pPackageStatics;
HRESULT hr = GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_ApplicationModel_Package).Get(), &_pPackageStatics);
ComPtr<ABI::Windows::ApplicationModel::IPackage> _pIPackage;
hr = _pPackageStatics->get_Current(&_pIPackage);
ComPtr<ABI::Windows::ApplicationModel::IPackage3> _pIPackage3;
hr = _pIPackage->QueryInterface(__uuidof(ABI::Windows::ApplicationModel::IPackage3), &_pIPackage3);
ComPtr<__FIAsyncOperation_1___FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry> _pAsyncOperation;
hr = _pIPackage3->GetAppListEntriesAsync(&_pAsyncOperation);
std::shared_ptr<Concurrency::event> _completed = std::make_shared<Concurrency::event>();
_pAsyncOperation->put_Completed(Microsoft::WRL::Callback<Implements<RuntimeClassFlags<ClassicCom>, ABI::Windows::Foundation::IAsyncOperationCompletedHandler <__FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry*>, FtmBase >>
([&_completed](ABI::Windows::Foundation::IAsyncOperation<__FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry*>* pHandler, AsyncStatus status)
{
__FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry* _pResults = nullptr;
HRESULT hr = pHandler->GetResults(&_pResults);
ComPtr<ABI::Windows::ApplicationModel::Core::IAppListEntry> _pIAppListEntry;
unsigned int _actual;
hr = _pResults->GetMany(0, 1, &_pIAppListEntry, &_actual);
ComPtr<ABI::Windows::ApplicationModel::IAppDisplayInfo> _pDisplayInfo;
hr = _pIAppListEntry->get_DisplayInfo(&_pDisplayInfo);
Microsoft::WRL::Wrappers::HString _HStrDisplayName;
hr = _pDisplayInfo->get_DisplayName(_HStrDisplayName.GetAddressOf());
const wchar_t * _pWchar_displayName = _HStrDisplayName.GetRawBuffer(&_actual);
OutputDebugString(_pWchar_displayName);
_completed->set();
return hr;
}).Get());
_completed->wait();
};
};
}
This outputted:
TestWinRtAsync10
Just in case anyone needs here is solution in C++/WinRT. Say you have function ProcessFeedAsync() that would return IAsyncAction, just need following simple code:
winrt::init_apartment();
auto processOp{ ProcessFeedAsync() };
// do other work while the feed is being printed.
processOp.get(); // no more work to do; call get() so that we see the printout before the application exits.
source
The compilation warnings below are not so clear to me, appart from the
deprecation warhing, but the signature of the method in the valadoc :
http://valadoc.org/#!api=gstreamer-1.0/Gst
shows no other method signature.
the other warning are more obscure.
max#max-ubuntu:~/mdev/cr valac --pkg gstreamer-0.10 gstpipe.vala
/home/max/dev/main-sandbox/cr/gstpipe.vala.c: In function ‘application_message’:
/home/max/dev/main-sandbox/cr/gstpipe.vala.c:64:2: warning: passing argument 1 of ‘_gst_structure_copy0’ discards ‘const’ qualifier from pointer target type [enabled by default]
/home/max/dev/main-sandbox/cr/gstpipe.vala.c:26:17: note: expected ‘gpointer’ but argument is of type ‘const struct GstStructure *’
/home/max/dev/main-sandbox/cr/gstpipe.vala.c:82:9: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
/home/max/dev/main-sandbox/cr/gstpipe.vala.c: In function ‘main’:
/home/max/dev/main-sandbox/cr/gstpipe.vala.c:173:2: warning: ‘g_type_init’ is deprecated (declared at /usr/include/glib-2.0/gobject/gtype.h:669) [-Wdeprecated-declarations]
using Gst;
void application_message(Gst.Bus bus, Gst.Message msg) {
var s = msg.get_structure();
if(s == null)
return;
string msgtype = s.get_name();
if(msgtype != "level")
return;
GLib.Value rms = s.get_value("rms");
//GLib.Value st = s.get_value("stream-time");
GLib.DateTime now = new GLib.DateTime.now_local();
var sec = now.to_unix();
var msec = (sec * 1000) + now.get_microsecond();
var z = rms.strdup_contents();
//z = z.replace("{", "[").replace("}", "]");
stdout.printf("%ld, %s \n", (long) msec, z);
}
void main (string[] args) {
Gst.init (ref args);
try {
var pipeline = Gst.parse_launch(
"pulsesrc device=\"alsa_input.usb-046d_08c9_674634A4-02-U0x46d0x8c9.analog-mono\" ! " +
"level name=wavelevel interval=10000000 ! " +
"wavenc ! filesink location=audioz.wav"
);
var bus = pipeline.get_bus();
bus.add_signal_watch();
bus.message.connect(application_message);
// Set pipeline state to PLAYING
pipeline.set_state (State.PLAYING);
// Creating and starting a GLib main loop
new MainLoop ().run ();
}
catch(Error e) {
print("%s\n", e.message);
}
}
You can generally ignore warnings from the C compiler when using Vala. Vala has better information than the C compiler, so it knows certain things are valid when the C compiler has no way of knowing that. Unfortunately we can't just add casts everywhere since there are situations where we can't generate a valid cast (and, what's more, no way to know what those situations are).
The final warning, about g_type_init being deprecated, is because g_type_init is no longer necessary as of glib 2.36. You can get rid of that warning by passing --target-glib=2.36 (or any later version of glib) to valac, but be warned that the generated code may no longer work with older versions of glib.
TBH, I often just pass -X -w to valac to get the C compiler to be quiet. Occasionally I miss a useful warning, but it gets rid of a lot of useless warnings.
I use the following code for Text-To-Speech application controls for blind persons in C++ Builder (most likely similar example can be used in Delphi). Main form has KeyPreview property checked to enable key F11 preview to start speaking active (focused) control. The code as it is works but there are some problems. This example is in C++ Builder code but from what I've found, Delphi suffers from same problem and the solution I found is the same. If you have Delphi solution, feel free to post it, it is similar anyway.
#include <sapi.h>
#include <WTypes.h>
//---------------------------------------------------------------------------
// Speak text string (synchronous function)
//---------------------------------------------------------------------------
bool SpeakText(UnicodeString Text)
{
ISpVoice* pVoice = NULL;
if (FAILED(::CoInitialize(NULL))) return false;
Word Saved8087CW = Default8087CW; // Disable floating point division by zero exception caused by Speak
Set8087CW(0x133f);
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
if (SUCCEEDED(hr))
{
//pVoice->SpeakCompleteEvent()
//pVoice->SetSyncSpeakTimeout(1000);
hr = pVoice->Speak(WideString(Text).c_bstr(), SPF_DEFAULT, NULL);
pVoice->Release();
pVoice = NULL;
}
Set8087CW(Saved8087CW);
::CoUninitialize();
return true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift)
{
UnicodeString Speaker;
if (Key == VK_F11)
{
if (Screen->ActiveControl->InheritsFrom(__classid(TButton))) { Speaker += "Button, " + static_cast<TButton*>(Screen->ActiveControl)->Caption + "."; }
else if (Screen->ActiveControl->InheritsFrom(__classid(TEdit))) { Speaker += "Edit box, " + static_cast<TEdit*>(Screen->ActiveControl)->Text + "."; }
}
if (Speaker != "") SpeakText(Speaker);
}
//---------------------------------------------------------------------------
Problems:
pVoice->Speak causes Floating point division by zero if I don't override the exception using the Set8087CW function. This happens only on Windows 7 (possibly Vista and Windows 8 too) but not on Windows XP in the same program (compiled exe). Is there a solution without using Set8087CW? Removing these lines will cause the problem and exception. I have BCB2010.
Function is synchronous and won't shut up or return control to program until it finishes reading text. This is a problem for longer text. It also blocks program events. Is there a way to make it asynchronous or introduce an event to periodically check for F11 key status and if F11 is pressed again it stops reading and uninitializes object? For example poll every 300 ms (or after each word etc.) for key-press F11 and if pressed, stop speaking? Or run it threaded?
Does SAPI has memory leaks as some write on various sites?
Can above code use OleCheck instead of CoCreateInstance and CoUninitialize?
UPDATE for those looking for solution as suggested by Remy Lebeau:
SavedCW = Get8087CW();
Set8087CW(SavedCW | 0x4);
hr = pVoice->Speak(WideString(Text).c_bstr(), SPF_DEFAULT | SPF_ASYNC, NULL);
pVoice->WaitUntilDone(-1); // Waits until text is done... if F11 is pressed simply go out of scope and speech will stop
Set8087CW(SavedCW);
Also found detailed example in CodeRage 4 session: http://cc.embarcadero.com/item/27264
The error does occur in Vista as well. Masking floating point exceptions is the only solution.
To make Speak() run asynchronously, you need to include the SPF_ASYNC flag when calling it. If you need to detect when asynchronous speaking is finished, you can use ISpVoice::WaitUntilDone(), or call ISpVoice::SpeakCompleteEvent() and pass the returned HANDLE to one of the WaitFor...() family of functions, like WaitForSingleObject().
What kind of leaks do other sites talk about?
Not instead of, no. OleCheck() merely checks the value of an HRESULT value and throws an exception if it is an error value. You still have to call COM functions that return the actual HRESULT values in the first place. If anything, OleCheck() would be a replacement for SUCCEEDED() instead.
For what you are attempting, I would suggest the following approach instead:
struct s8087CW
{
Word Saved8087CW;
s8087CW(Word NewCW)
{
Saved8087CW = Default8087CW;
Set8087CW(NewCW);
// alternatively, the VCL documentation says to use SetExceptionMask() instead of Set8087CW() directly...
}
~s8087CW()
{
Set8087CW(Saved8087CW);
}
};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{
::CoInitialize(NULL);
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
if (pVoice) pVoice->Release();
::CoUninitialize();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift)
{
if (Key == VK_F11)
{
TWinControl *Ctrl = Screen->ActiveControl;
if (Ctrl)
{
TButton *btn;
TEdit *edit;
if ((btn = dynamic_cast<TButton*>(Ctrl)) != NULL)
SpeakText("Button, " + btn->Caption);
else if ((edit = dynamic_cast<TEdit*>(Ctrl)) != NULL)
SpeakText("Edit box, " + edit->Text);
}
}
}
//---------------------------------------------------------------------------
ISpVoice* pVoice = NULL;
bool __fastcall TForm1::SpeakText(const String &Text)
{
s8087CW cw(0x133f);
if (!pVoice)
{
if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice)))
return false;
}
SPVOICESTATUS stat;
pVoice->GetStatus(&stat, NULL);
while (stat.dwRunningState == SPRS_IS_SPEAKING)
{
ULONG skipped;
pVoice->Skip(L"SENTENCE", 1000, &skipped);
pVoice->GetStatus(&stat, NULL);
}
return SUCCEEDED(pVoice->Speak(WideString(Text).c_bstr(), SPF_ASYNC, NULL));
}
I have a C process that is rapidly writing to a mysql database ~10 times per second. This process uses the MySql C Connector.
After about 2 minutes of running, the process hangs and in system monitor shows
"futex_wait_queue_me"
, and also
"Can't initialized threads: error 11"
is printed to console, I assume by the C connector library(since I do not print this). Following that write, connections to mysql fail with
"MySQL server has gone away".
What could be causing this? I am only writing from 1 thread.
fyi, I am using the library as so. mutex lock and unlock are there for future as i will be multithreading the logging. The logging events in actual app will be much less frequent, but I am trying to stress it as much as possible in this particular test.
//pseudocode:
while(1)
mutexlock
connect();
mysql_query();
disconnect();
sleep(100ms);
mutexunlock
A better solution, maybe not the best
connect();
while(1)
mutexlock
if error on mysql_query();
disconnect();
connect();
sleep(100ms);
mutexunlock
//connect/disconnect functions
int DBConnector::connect()
{
if(DBConnector::m_isConnected) return 0;//already connected...
if(!mutexInitialized)
{
pthread_mutex_init(&DBLock, 0);
}
if(mysql_library_init(0, NULL, NULL))
{
LoggingUtil::logError("DBConnector.DB_connect [DB library init error] " + string(mysql_error(&DBConnector::m_SQLHandle)));
DBConnector::m_isConnected = false;
return -1;
}
if((mysql_init(&m_SQLHandle)) == NULL)
{
LoggingUtil::logError("DBConnector.DB_connect [DB mysql init error] " + string(mysql_error(&DBConnector::m_SQLHandle)));
DBConnector::m_isConnected = false;
return -1;
}
if((mysql_real_connect(&DBConnector::m_SQLHandle, host.c_str(), user.c_str(), pw.c_str(), db.c_str(), port, socket.c_str(), client_flags)) == NULL)
{
LoggingUtil::logError("DBConnector.DB_connect [DB Connect error] " + string(mysql_error(&DBConnector::m_SQLHandle)));
DBConnector::m_isConnected = false;
return -1;
}
DBConnector::m_isConnected = true;
return 0;
}
int DBConnector::disconnect()
{
DBConnector::m_isConnected = false;
mysql_close(&DBConnector::m_SQLHandle);
mysql_library_end();
return 0;
}
Try to not call
mysql_library_init(0, NULL, NULL);
and
mysql_library_end();
at each connection attempt.
Also your second idea of not reconnecting at every mysql-access is much better as establishing a connection will always take some time/resource. For nothing in your case.
After a query has failed, you don't need to re-connect to the database.