Thread safe queue with front() + pop() - c++11

I have created a thread safe queue (see code). The class seems to work but now I want to make the combination front() plus pop() thread safe in such a way that a thread first gets the element and then for sure removes the same element. I can come up with some solutions but they are not elegant for the user side or the strong exception safety guarantee will be lost.
The first solution is that the user simply has to lock the ThreadQueueu than call front() and pop() and unlock the ThreadQueue. However, the whole idea of the class is that the user has not to mind about the thread safety.
The second solution is to lock the queue inside the overloaded function front() and only unlock it in pop(). However, in this case the user is not allowed to only call front() or pop(), not that user friendly..
The third option I came up with is to create a public function in the class (frontPop) which returns the front element and removes it. However in this case the exception safety is gone.
What is the solution which is both user friendly (elegant) and maintain the exception safety?
class ThreadQueue: private std::queue<std::string>
{
mutable std::mutex d_mutex;
public:
void pop()
{
lock_guard<mutex> lock(d_mutex);
pop();
}
std::string &front()
{
lock_guard<mutex> lock(d_mutex);
return front();
}
// All other functions
private:
};

The usual solution is to provide a combined front & pop that accepts a reference into which to store the popped value, and returns a bool that is true if a value was popped:
bool pop(std::string& t) {
lock_guard<mutex> lock(d_mutex);
if (std::queue<std::string>::empty()) {
return false;
}
t = std::move(std::queue<std::string>::front());
std::queue<std::string>::pop();
return true;
}
Any exceptions thrown by the move assignment happen before the queue is modified, maintaining the exception guarantee provided by the value type's move assignment operator.

Related

ConcurrentModificationException in Java Stream but not in for loop with counter

I am removing comment nodes with jsoup and found something I do not understand.
This code works:
Example 1:
private static void removeComments(Node node) {
for (int i = 0; i < node.childNodes().size();) {
Node child = node.childNode(i);
if (child.nodeName().equals("#comment"))
child.remove();
else {
removeComments(child);
i++;
}
}
But this code throws an ConcurrentModificationException:
Example 2
private static void removeComments(Node node) {
node.childNodes()
.forEach(n -> {
if (n.nodeName().equals("#comment")) {
n.remove();
} else {
removeComments(n);
}
});
}
I try to write short, easy to understand code, ternary operator not supporting two void returns already destroyed my "oneline" approach. What limitation did I hit with that strange behaviour?
ConcurrentModificationException occurs when you modify the list (by adding or removing elements) while traversing a list with an Iterator.
You can't modify a List in a for/each loop, which is syntactic sugar around the Iterator as an implementation detail. You can only safely call .remove() when using the Iterator directly.
Calling .remove() inside the for/each loop modifies the contents, and the Iterator that is used behind the scenes sees this and throws this exception.
Read about How to Avoid ConcurrentModificationException when using an Iterator.

Are static lambdas of any use/unwise?

I'm trying to track a very difficult to reproduce bug. I have a pool of items and use the following to automatically check the pool items back in when the client has finished with them:
typedef std::shared_ptr<T> Handle;
Handle MyPool::checkOut()
{
static const auto CheckInDeleter = [this](T* item)
{
this->checkIn(item);
};
return Handle(item, CheckInDeleter);
}
My question is is this unsafe? Will this be assigned to the first pool that checks out an item?
Yes, static function-scope variables are assigned once,so there will be only one lambda object, that will refer to first MyPool that has checkOut member function called. It is probably not what you need, so just remove static.

Implementing an asynchronous delay in C++/CX

I am trying to write a function which, given a number of seconds and a callback, runs the callback after the given number of seconds. The callback does not have to be on the same thread. The target language is C++/CX.
I tried using Windows::System::Threading::ThreadPoolTimer, but the result is a memory access exception. The issue appears to be that the callback implementation (in native C++) can't be accessed from the managed thread that the timer is running its callback on.
ref class TimerDoneCallback {
private:
function<void(void)> m_callback;
public:
void EventCallback(ThreadPoolTimer^ timer) {
m_callback(); // <-- memory exception here
}
TimerDoneCallback(function<void(void)> callback) : m_callback(callback) {}
};
void RealTimeDelayCall(const TimeSpan& duration, function<void(void)> callback) {
auto t = ref new TimerDoneCallback(callback);
auto e = ref new TimerElapsedHandler(t, &TimerDoneCallback::EventCallback);
ThreadPoolTimer::CreateTimer(e, duration);
}
void Test() {
RealTimeDelayCall(duration, [](){}); //after a delay, run 'do nothing'
}
I don't want to create a thread and sleep on it, because there may be many concurrent delays.
The TimerDoneCallback instance is not kept alive - delegates in C++/CX take weak references to the target object (to avoid circular references). You can override this behavior by using the extended overload of the delegate constructor:
auto e = ref new TimerElapsedHandler(t, &TimerDoneCallback::EventCallback, CallbackContext::Any, true);
The final bool parameter should be true for strong references, and false for weak references. (False is the default.)
You could also consider using the timer class in PPL agents to make a delayed callback: http://msdn.microsoft.com/en-us/library/hh873170(v=vs.110).aspx to avoid needing to use ThreadPoolTimer.

D Analogue to C++ member-function-pointers, not necessarily delegates

I have been learning D, and am in particular very excited for it's Generic programming capabilities. Delegates are wonderful, and apparently they have completely replaced member-function-pointers, so I was stuck when I wanted to implement something like the following:
template <typename T>
void DispatchMethodForAll(std::vector<T*> & container, void (T::* func)(void))
{
for(typename std::vector<T*>::iterator it = container.begin(); it != container.end(); ++it)
(*it)->*func();
}
According to what I have learned of function pointers and delegates in D, is that neither of them can do this, since function pointers can only be declared for global functions, and delegates have to be bound to an object, there is no "partial delegate" that I can find. As seen here, I cannot use a delegate, since there is no single object that can be bound to the method that is to be called.
I know that I could do it with mixins, and essentially make it a macro. However this really doesn't sound D-like, and I figured there should be "The correct way"
You could still use a delegate here.
void DispatchMethodForAll(T)(T*[] container, void delegate(T*) action)
{
foreach (it; container)
action(it);
}
...
DispatchMethodForAll(container, (Foo* foo) { foo.func(); });
Example: http://www.ideone.com/9HUJa
you can take a page out of the std.algorithm to find out how it does that
void DispatchMethodForAll(alias func, T)(T container)
{
alias unaryFun!func _func
foreach (it; container)
_func(it);
}
btw a delegate can be bound to a struct and the compiler can create a custom struct from local (stack allocated) variables and define a delegate on that
this happens with
void foo(){
int[] array;
int i=0;
void bar(int a){
i+=a;
}
void DispatchMethodForAll(&bar)(array);
writeln(i);//prints the sum of array
}
bar is a delegate bound to a struct with (at least) a member i of type int of which the local variable i is an alias

Subscription to DTE events doesn't seem to work - Events don't get called

I've made an extension inside a package and I am calling the following code (occurs when a user presses a button in the toolbar):
DocumentEvents documentEvents = (DTE2)GetService(typeof(DTE));
_dte.Events.DebuggerEvents.OnEnterBreakMode += DebuggerEvents_OnEnterBreakMode;
_dte.Events.DebuggerEvents.OnEnterDesignMode += DebuggerEvents_OnEnterDesignMode;
_dte.Events.DebuggerEvents.OnContextChanged += DebuggerEvents_OnContextChanged;
_dte.Events.DocumentEvents.DocumentSaved += new _dispDocumentEvents_DocumentSavedEventHandler(DocumentEvents_DocumentSaved);
_dte.Events.DocumentEvents.DocumentOpened += new _dispDocumentEvents_DocumentOpenedEventHandler(DocumentEvents_DocumentOpened);
void DocumentEvents_DocumentOpened(Document Document)
{
}
void DocumentEvents_DocumentSaved(Document Document)
{
}
void DebuggerEvents_OnEnterBreakMode(dbgEventReason Reason, ref dbgExecutionAction ExecutionAction)
{
}
void DebuggerEvents_OnContextChanged(Process NewProcess, Program NewProgram, Thread NewThread, StackFrame NewStackFrame)
{
}
private void DebuggerEvents_OnEnterDesignMode(dbgEventReason reason)
{
}
The first and the major problem is that the subscription to the event doesn't work. I've tried:
Opening new documents
Detaching from debug (thus supposedly triggering OnEnterDesignMode
Saving a document
None of these seem to have any effect and the callback functions were never called.
The second issue is that the subscription to the event line works USUALLY (the subscription itself, the callback doesn't work as described above) but after a while running the subscription line, e.g:
_dte.Events.DebuggerEvents.OnEnterBreakMode -= DebuggerEvents_OnEnterBreakMode;
Causes an exception:
Exception occured!
System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.
at System.StubHelpers.StubHelpers.StubRegisterRCW(Object pThis, IntPtr pThread)
at System.Runtime.InteropServices.UCOMIConnectionPoint.Unadvise(Int32 dwCookie)
at EnvDTE._dispDebuggerEvents_EventProvider.remove_OnEnterDesignMode(_dispDebuggerEvents_OnEnterDesignModeEventHandler A_1)
Any ideas will be welcome
Thanks!
Vitaly
Posting an answer that I got from MSDN forums, by Ryan Molden, in case it helps anyone:
I believe the problem here is how the
CLR handles COM endpoints (event
sinks). If I recall correctly when
you hit the
_applicationObject.Events.DebuggerEvents
part of your 'chain' the CLR will
create a NEW DebuggerEvents object for
the property access and WON'T cache
it, therefor it comes back to you, you
sign up an event handler to it (which
creates a strong ref between the
TEMPORARY object and your object due
to the delegate, but NOT from your
object to the temporary object, which
would prevent the GC). Then you don't
store that object anywhere so it is
immediately GC eligible and will
eventually be GC'ed.
I changed the code to store DebuggerEvents as a field and it all started to work fine.
Here is what #VitalyB means using code:
// list where we will place events.
// make sure that this variable is on global scope so that GC does not delete the evvents
List<object> events = new List<object>();
public void AddEvents(EnvDTE dte)
{
// create an event when a document is open
var docEvent = dte.Events.DocumentEvents;
// add event to list so that GC does not remove it
events.Add(docEvent );
docEvent.DocumentOpened += (document)=>{
Console.Write("document was opened!");
};
// you may add more events:
var commandEvent = dte.Events.CommandEvents;
events.Add(commandEvent );
commandEvent.AfterExecute+= etc...
}

Resources