Calling method with array or arguments using QueuedConnection - multithreading

I want to call arbitrary slot of QObject in other thread.
I have:
| Arguments: | Can use QueuedConnection?
QMetaObject::invokeMethod | fixed number | YES
qt_metacall | array | NO
I want:
<something> | array | YES
I don't want to do things like duplicating invokeMethod code based on the number of arguments.
Where to get invokeMethod that accepts array of arguments or how to make qt_metacall queued?

You can either:
write a signal with the same default parameters as the slot you want to call, connect it to the slot with Qt::QueuedConnection and call the signal with qt_metacall and your array, or
write a QObject derived class that:
takes your parameter array as parameter for its constructor, and stores it internally,
calls QMetaObject::invokeMethod in the constructor with Qt::QueuedConnection to invoke a slot without parameter which will call qt_metacall with the stored parameter array before deleting the QObject.
Internally Qt uses the 2nd method but with a internal class: QMetaCallEvent (in corelib/kernel/qobject_p.h) and postEvent instead of a signal/slot connection.

Working around by creating array initialized by GenericArgument:
QGenericArgument args[] = {
QGenericArgument(), ....... ,QGenericArgument(),};
for (int p = 0; p < parameterTypes.count(); ++p) {
QVariant::Type type = QVariant::nameToType(parameterTypes.at(p));
switch(type) {
case QVariant::String:
args[p] = Q_ARG(QString, obtainTheNextStringArgument());
break;
// the rest needed types here
}
}
mm.invoke(object, Qt::QueuedConnection, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8],args[9]);

Related

NPE when retrieving from HashMap even though containsKey() returns true in multithreaded environment

We are trying to store unique object for a particular key. When getMyObject is called in multithreaded environment we are getting null ptr exception at the time of return statement
object SampleClass
{
fun getMyObject(Id : String) : MyObject
{
if(!myMap.containsKey(Id))
{
synchronized(SampleClass)
{
if(!myMap.containsKey(Id))
{
myMap[Id] = MyObject()
}
}
}
return myMap[Id]!!
}
private val myMap = HashMap<String,MyObject>()
}
It seems even though contains method returns true when we try to get the value the value is returned null.
I am not sure what is the reason behind it.
This is the kind of trouble you get into if you try to outsmart the memory model. If you look at HashMap's source, you'll find containsKey implemented as:
public boolean containsKey(Object key) {
return getNode(key) != null;
}
Note that it returns true only if there's a HashMap.Node object corresponding to the given key. Now, this is how get is implemented:
public V get(Object key) {
Node<K,V> e;
return (e = getNode(key)) == null ? null : e.value;
}
What you're seeing is an instance of the unsafe publication problem. Let's say 2 threads (A & B) call getMyObject for a non-existent key. A is slightly ahead of B, so it gets into the synchronized block before B calls containsKey. Particularly, A calls put before B calls containsKey. The call to put creates a new Node object and puts it into the hash map's internal data structures.
Now, consider the case when B calls containsKey before A exists the synchronized block. B might see the Node object put by A, in such case containsKey returns true. At this point, however, the node is unsafely published, because it is accessed by B concurrently in a non-synchronized manner. There's no guarantee its constructor (the one setting its value field) has been called. Even if it was called, there's no guarantee the value reference (or any references set by the constructor) is published along with the node reference. This means B can see an incomplete node: the node reference but not its value or any of its fields. When B proceeds to get, it reads null as the value of the unsafely published node. Hence the NullPointerException.
Here's an ad-hoc diagram for visualizing this:
Thread A Thread B
- Enter the synchronized block
- Call hashMap.put(...)
- Insert a new Node
- See the newly inserted (but not yet
initialized from the perspective of B)
Node in HashMap.containsKey
- Return node.value (still null)
from HashMap.get
- !! throws a `NullPointerException`
...
- Exit the synchronized block
(now the node is safely published)
The above is just one scenario where things can go wrong (see comments). To avoid such hazards, either use a ConcurrentHashMap (e.g. map.computeIfAbsent(key, key -> new MyObject())) or never access your HashMap concurrently outside of a synchronized block.

Is it possible using variables of ArgumentMatchers?

Let's say I have an interface looks like this.
interface Some {
/**
* Does some on specified array with specified index and returns the array.
*
* #param array the array.
* #param index the index.
* #returns given {#code array}.
*/
byte[] some(byte[] array, int index);
}
Here comes a simple stubbing make the some method just return given array.
Some some = spy(Some.class);
when(some.some(any(), anyInt())
.thenAnswer(i -> i.getArguments(0)};
Is it possible or does it make any sense modifying above code like this?
Some some = spy(Some.class);
byte[] array = any(); // ##?
int index = anyInt(); // ##?
when(some.some(array, index) // ##?
.thenAnswer(i -> i.getArguments(0)};
Does it have same or equivalent effects?
In the code posted, the test passes and the effect is equivalent. This is not true in the general case, and you can easily break the code.
For example this works:
Some some = mock(Some.class);
byte[] any = any();
int index = anyInt();
when(some.some(any, index)).thenAnswer(i -> i.getArguments()[0]);
var res = some.some(new byte[]{1, 2}, 4);
While this with reordered variables does not work:
Some some = mock(Some.class);
int index = anyInt();
byte[] any = any();
when(some.some(any, index)).thenAnswer(i -> i.getArguments()[0]);
var res = some.some(new byte[]{1, 2}, 4);
Please refer to How do Mockito matchers work?:
Implementation details
Matchers are stored (as Hamcrest-style object matchers) in a stack contained in a class called ArgumentMatcherStorage. MockitoCore and Matchers each own a ThreadSafeMockingProgress instance, which statically contains a ThreadLocal holding MockingProgress instances. It's this MockingProgressImpl that holds a concrete ArgumentMatcherStorageImpl. Consequently, mock and matcher state is static but thread-scoped consistently between the Mockito and Matchers classes.
Most matcher calls only add to this stack, with an exception for matchers like and, or, and not. This perfectly corresponds to (and relies on) the evaluation order of Java, which evaluates arguments left-to-right before invoking a method:
when(foo.quux(anyInt(), and(gt(10), lt(20)))).thenReturn(true);
[6] [5] [1] [4] [2] [3]
This will:
Add anyInt() to the stack.
Add gt(10) to the stack.
Add lt(20) to the stack.
Remove gt(10) and lt(20) and add and(gt(10), lt(20)).
Call foo.quux(0, 0), which (unless otherwise stubbed) returns the default value false. Internally Mockito marks quux(int, int) as the most recent call.
Call when(false), which discards its argument and prepares to stub method quux(int, int) identified in 5. The only two valid states are with stack length 0 (equality) or 2 (matchers), and there are two matchers on the stack (steps 1 and 4), so Mockito stubs the method with an any() matcher for its first argument and and(gt(10), lt(20)) for its second argument and clears the stack.
This demonstrates a few rules:
Mockito can't tell the difference between quux(anyInt(), 0) and quux(0, anyInt()). They both look like a call to quux(0, 0) with one int matcher on the stack. Consequently, if you use one matcher, you have to match all arguments.
Call order isn't just important, it's what makes this all work. Extracting matchers to variables generally doesn't work, because it usually changes the call order. Extracting matchers to methods, however, works great.
int between10And20 = and(gt(10), lt(20));
/* BAD */ when(foo.quux(anyInt(), between10And20)).thenReturn(true);
// Mockito sees the stack as the opposite: and(gt(10), lt(20)), anyInt().
public static int anyIntBetween10And20() { return and(gt(10), lt(20)); }
/* OK */ when(foo.quux(anyInt(), anyIntBetween10And20())).thenReturn(true);
// The helper method calls the matcher methods in the right order.

Kotlin local variable thread safety

So I was writing a unit test to test some multi-threading, and I want to know if this code is guaranteed to work as I would expect.
fun testNumbers() {
var firstNumber: Int? = null
var secondNumber: Int? = null
val startLatch = CountDownLatch(2)
val exec = Executors.newFixedThreadPool(2)
exec.submit({
startLatch.countDown()
startLatch.await()
firstNumber = StuffDoer.makeNumber()
})
exec.submit({
startLatch.countDown()
startLatch.await()
secondNumber = StuffDoer().makeNumber()
})
while (firstNumber == null || secondNumber == null) {
Thread.sleep(1)
}
}
Specifically, is this method guaranteed to complete? firstNumber and secondNumber aren't volatile so does that mean the results set in those values from the exec threads might never be seen by the thread running the test? You can't apply volatile to local variables, so practically speaking it wouldn't make sense to me that you can't make function-local variables volatile if it might be necessary.
(I added Java as a tag because presumably the basic question is the same in Java.)
When compiled with the Kotlin 1.1 RC compiler, the local variables in your code are stored in ObjectRefs, which are then used in the lambdas.
You can check what a piece of code is compiled to using the Kotlin bytecode viewer.
ObjectRef stores the reference in a non-volatile field, so there is indeed no guarantee that the program completes.
Earlier versions of Kotlin used to have a volatile field in the Ref classes, but this was an undocumented implementation detail (i.e. not something to rely on) that has eventually been changed in Kotlin 1.1. See this thread for the motivation behind the non-volatile captured variables.
As said in the issue description,
If a user is capturing a variable and handing it to other threads to work with, then it is a requirement of whatever concurrency control mechanism they are using to establish the corresponding happens-before edges between reads and writes to the captured variables. All regular concurrency mechanisms like starting/joining threads, creating futures, etc do so.
To make your example program correctly synchronized, it is enough to call .get() on the two Future instances returned from exec.submit { }, since Future provides happens-before guarantees:
Actions taken by the asynchronous computation represented by a Future happen-before actions subsequent to the retrieval of the result via Future.get() in another thread.
val f1 = exec.submit { /* ... */ }
val f2 = exec.submit { /* ... */ }
f1.get()
f2.get()
// Both assignments made in the submitted tasks are visible now
assert(firstNumber != null)
assert(secondNumber != null)

Threads with same argument objects give different values

I have a problem where two threads with different functions and same argument objects result in giving different values for those objects.
To clearify, please observe the following code:
class Player(){
// Definition of Player here
// with get- and set functions
// for a certain value.
}
class Game(){
static void Draw(Player p){
while(1){
gotoxy(p.getValue(), 15);
cout << p.name();
}
}
static void Move(Player p){
int x = p.getValue();
while(1){
if(_kbhit()){
p.setValue(++x);
}
}
}
void startGame(){
Player pl1(5);
thread thd1(Move, pl1);
thread thd2(Draw, pl1);
thd1.join();
thd2.join();
}
}
While the value 'x' is changing in the function 'Move' for every key stroke, when getting that value in function 'Draw' still has the initial value for 'pl1' (which is 5).
How can I get 'Draw' to aquire the same value that 'Move' has given?
I appreciate any help and guidance.
Thank you in advance!
You are passing the player by value
static void Move(Player pl)
rather than by reference/pointer, so both functions have their own, local, copies of the original variable.
static void Move(Player& pl)
will take the variable by reference and give both functions access to the original variable.
Also, unless getValue and setValue implement some form of locking, this code is not thread safe.
The problem is that you are passing pl1 by value, when you want to be passing it by reference. Even though it looks like you are passing pl1 into each function, what's really going on is that the Move and Draw threads are each constructing new Player objects. If you pass by references, then both threads will refer to the same object as opposed to creating their own copies. Try changing the signatures of the functions to the following:
static void Move(Player &p);
static void Draw(Player &p);
Also, consider putting some exit condition into your function. Since while(1) will never exit, the join() functions will wait forever. Hope that helps!

How to send enum type to Invoke (delegate) Visual C++

I've a function to modify a PictureBox, so I need to use a delegate. My function needs an int in order to do its job, and I've created an enum in order to define the values it can have.
However, when I'm invoking it, there's a problem because it cannot convert from my enum to object, in order to send it the the function.
How can I face it?
My function:
System::Void modifyButtonPicture(int estado)
The enum:
enum BUTTON_STATE : int { PB_STOP = 0, PB_PLAY = 1 };
Delegate:
delegate void SetTextDelegatePlayButton(int estado);
Invoke:
Invoke(gcnew SetTextDelegatePlayButton(this, &Form1:: modifyButtonPicture), PB_PLAY);
The error message (translated):
error C2664: 'System::Object ^System::Windows::Forms::Control::Invoke(System::Delegate ^,...cli::array<Type> ^)' : cannot convert 2nd parameter from 'BUTTON_STATE' to 'System::Object ^'
As documented by MSDN Control::Invoke Method (Delegate, array) the Invoke method accepts these parameters:
method
Type: System::Delegate
A delegate to a method that takes parameters of the same number and type that >are contained in the args parameter.
args
Type: array
An array of objects to pass as arguments to the specified method. This parameter can be nullptr if the method takes no arguments.
And in your call, your passing an int as the second parameter (the PB_PLAY).
So you need to cast your enum to an System::Object array:
int play = (int)PB_PLAY;
array<Object^>^myEnumArray = {play};
Invoke(gcnew SetTextDelegatePlayButton(this, &Form1:: modifyButtonPicture), myEnumArray);

Resources