Immutable object pattern - thread-safety

I keep hearing that using immutable data structures and immutable objects is a good pattern for thread safety and preventing race conditions without needing to use semaphores, but I still can't think of a way to use them. Even for the most simple scenarios. For example
int a = 0;
Semaphore s = new Semaphore();
void thread1() {
s.wait();
if (a == 2) {
// do something
}
a = 1;
s.signal();
}
void thread2() {
s.wait();
if (a == 1) {
// do something
}
a = 2;
s.signal();
}
How can I change this code to use an immutable object for a?

Related

Recursion over a mutable binary tree: `already borrowed: BorrowMutError`

I'm beginning with a Vec of sorted nodes, then using this sorting to link these nodes together in a binary tree and then returning the base struct
// Test name
#[derive(Clone)]
struct Struct {
parent: Option<Rc<RefCell<Struct>>>,
superscript: Option<Rc<RefCell<Struct>>>,
subscript: Option<Rc<RefCell<Struct>>>,
height: u32,
center: u32,
symbols: VecDeque<u8>
}
Ending up with a binary tree formed by the above Structs. At this point, these Structs are uniquely owned, so I think I could convert from using Rc<RefCell<Struct>> to RefCell<Struct> (think Box<Struct> doesn't work due to internal mutability?), but I'm not sure how or if this helps with the problem I'm encountering.
After this, I need to iterate in a novel manner through the Structs, and mutate the various symbols belonging to the various Structs throughout the recursion, via calling .pop_front().
My current implementation doing this leads to various instances of thread 'main' panicked at 'already borrowed: BorrowMutError'.
Playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=636c93088f5a431d0d430d42283348f3
The function for it (please excuse the convoluted logic):
fn traverse_scripts(row: Rc<RefCell<Struct>>) {
if let Some(superscript_row) = &row.borrow().superscript {
if let Some(superscript_symbol) = superscript_row.borrow().symbols.front() {
if let Some(current_row_symbol) = row.borrow().symbols.front() {
if superscript_symbol < current_row_symbol {
println!("^{{{}",*superscript_symbol);
superscript_row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(superscript_row));
}
}
else {
println!("^{{{}",*superscript_symbol);
superscript_row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(superscript_row));
}
}
}
if let Some(subscript_row) = &row.borrow().subscript {
if let Some(subscript_symbol) = subscript_row.borrow().symbols.front() {
if let Some(current_row_symbol) = row.borrow().symbols.front() {
if subscript_symbol < current_row_symbol {
print!("_{{{}",*subscript_symbol);
subscript_row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(subscript_row));
}
}
else {
print!("_{{{}",*subscript_symbol);
subscript_row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(subscript_row));
}
}
}
if let Some(current_row_symbol) = row.borrow().symbols.front() {
if let Some(parent_row) = &row.borrow().parent {
if let Some(parent_symbol) = parent_row.borrow().symbols.front() {
if current_row_symbol < parent_symbol {
print!(" {}",*current_row_symbol);
row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(&row));
}
}
}
else {
print!(" {}",*current_row_symbol);
row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(&row));
}
}
if let Some(parent_row) = &row.borrow().parent {
if let Some(parent_symbol) = parent_row.borrow().symbols.front() {
print!("}} {}",*parent_symbol);
row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(parent_row));
} else {
print!("}}");
traverse_scripts(Rc::clone(parent_row));
}
}
}
I've considered using Arc<Mutex<Struct>> instead for the traversal, but given its not multi-threaded I don't think it's neccessary?
I imagine I might be missing a relatively simple idea here, I would really appreciate any help.
If I've missed anything in my question please drop a comment and I'll try to add it.
When you call borrow or borrow_mut on a RefCell, a guard object (Ref or RefMut) is created that grants access to the inner value for as long as it exists. This guard will lock the RefCell until it goes out of scope and is destroyed. Let's look at a portion of traverse_scripts:
if let Some(superscript_row) = &row.borrow().superscript { // row is borrowed
if let Some(superscript_symbol) = superscript_row.borrow().symbols.front() { // superscript_row is borrowed
if let Some(current_row_symbol) = row.borrow().symbols.front() { // row is borrowed again
if superscript_symbol < current_row_symbol {
println!("^{{{}", *superscript_symbol);
superscript_row.borrow_mut().symbols.pop_front(); // superscript_row is borrowed mutably (ERROR)
traverse_scripts(Rc::clone(superscript_row)); // recursive call while row and superscript_row are borrowed (ERROR)
}
} else {
println!("^{{{}", *superscript_symbol);
superscript_row.borrow_mut().symbols.pop_front(); // superscript_row is borrowed mutably (ERROR)
traverse_scripts(Rc::clone(superscript_row)); // recursive call while row and superscript_row are borrowed (ERROR)
} // row is no longer borrowed twice
} // superscript_row is no longer borrowed
} // row is no longer borrowed
In the first line, for example, row.borrow() returns a Ref<Struct>. This Ref can't be dropped immediately, because it's being borrowed during the if let body by superscript_row. So it stays alive that whole time -- until the final }.
This is a problem for recursively calling traverse_scripts because the Struct is borrowed during the entire recursive call. Any attempt to borrow the same Struct mutably deeper in the call stack will fail. (Borrowing it immutably does still work.)
In the second line superscript_row is borrowed. This has the same problem, but it also has a more immediate one: it's borrowed mutably later in the same function, even before hitting the recursive call. That borrow_mut can never succeed because superscript_row is always already borrowed at that point.
To fix both problems, we'll do two things:
Store each Ref or RefMut guard in a variable of its own and re-use that guard, instead of calling borrow() or borrow_mut() on the same variable again.
Before recursing, drop each of the still-living guards so that nothing is still borrowed inside the recursive call.
Here's what that section might look like rewritten:
{ // This scope will constrain the lifetime of row_ref
let row_ref = row.borrow();
if let Some(superscript_row) = &row_ref.superscript {
let mut child = superscript_row.borrow_mut(); // use borrow_mut here because we know we'll need it later
if let Some(superscript_symbol) = child.symbols.front() {
if let Some(current_row_symbol) = row_ref.symbols.front() {
if superscript_symbol < current_row_symbol {
println!("^{{{}", *superscript_symbol);
child.symbols.pop_front();
drop(child); // child is no longer needed, so drop it before recursing
// Since superscript_row borrows from row_ref, we must Rc::clone it before
// dropping row_ref so that we can still pass it to traverse_scripts.
let superscript_row = Rc::clone(superscript_row);
drop(row_ref); // row_ref is no longer needed, so drop it before recursing
traverse_scripts(superscript_row);
}
} else {
println!("^{{{}", *superscript_symbol);
child.symbols.pop_front();
// see comments earlier
drop(child);
let superscript_row = Rc::clone(superscript_row);
drop(row_ref);
traverse_scripts(superscript_row);
}
}
} // child is dropped here (if it wasn't already). superscript_row is no longer borrowed
} // row_ref is dropped here (if it wasn't already). row is no longer borrowed
Full-program playground.
This looks complicated because it is complicated. Traversing over a data structure while mutating it is a common source of bugs (in most languages, not just Rust). It looks like, in traverse_scripts at least, the only reason for needing mutation is to call pop_front on symbols, so if you can redesign the data structure such that only symbols is in a RefCell, you could do the traversal with only & references, which would be much easier. Another common approach is to write functions that return new data structures instead of mutating them in place.

What caused the memory leak in this code?

I am inspecting the code that may cause memory leak. I know something is wrong with std::set.erase(this) and the destructor of SomeObject. So how to fix it?
class SomeObject;
////....
std::set<SomeObject*> managedObjects;
///.....
class SomeObject{
public:
SomeObject(){ managedObjects.insert(this); }
SomeObject(SomeObject&& S)/*move cter*/{ managedObjects.insert(this); }
virtual ~SomeObject() { managedObjects.erase(this); }
////....
};
////....
void clearAllObjects() {
for(auto p : managedObjects){
if(p){
delete p;
}
}
managedObjects.clear();
}
////....
When you delete inside clearAllObjects() it will result in managedObjects.erase(this) which is the same as managedObjects.erase(p).
This means that the internal iterator in the range based for-loop may be invalidated (I'm not sure). If it is, it'll try to do ++internal_iterator; on an invalid iterator - with undefined behavior as a result.
To be safe, you could copy the iterator and step that to the next in the set before doing erase.
Also note: There's no need to check if what you delete is a nullptr or not. It's mandated by the standard to have no effect if that's the case.
Example:
void clearAllObjects() {
for(auto pit = managedObjects.begin(); pit != managedObjects.end();) {
delete *pit++ // postfix ++ returns a copy of the old iterator
}
managedObjects.clear();
}
A side effect by having this managedObjects set is that you can't have automatic variables of SomeObject.
int main() {
SomeObject foo;
clearAllObjects(); // deletes the automatic object "foo" (not allowed)
} // <- the automatic object is destroyed here

Correct way of synchronization between a method and a stop functionality

I have a function (lets call it function A) that 0 to many threads can access it (at the same time, no shared resources). At any given time, the user can use to stop the process. The stop functionality needs to make sure that there are threads accessing function A, so that a graceful shutdown can be performed. Is there a native procedure to do so?
What I was going to do is have an InterlockedIncrement an integer everytime function A is called (and a corresponding InterlockedDecrement on said integer when function A exists). When an InterlockedDecrement takes place, it checks the value of the integer, if it's set to zero, a event is set to signalled. If the value is not zero, the event is set to nonsignalled.
This makes sense in my mind, but I'm curious whether there is a more native structure / functionality adapted to do so.
I still have to thing about the fact the "stop" function may get starved (in the sense, the said integer may never be set to zero). A sidenote: when the stop event takes place, the InterlockedIncrement process shall be stopped, to reduce said starvation.
what you need and want implement is called Run-Down Protection. unfortunately it supported only in kernel mode, but not hard implement it yourself in user mode too.
the simplest implementation is next:
HANDLE ghStopEvent;
LONG gLockCount = 1;
BOOLEAN bStop = FALSE;
void unlock()
{
if (!InterlockedDecrement(&gLockCount)) SetEvent(ghStopEvent);
}
BOOL lock()
{
LONG Value = gLockCount, NewValue;
for ( ; !bStop && Value; Value = NewValue)
{
NewValue = InterlockedCompareExchange(&gLockCount, Value + 1, Value);
if (NewValue == Value) return TRUE;
}
return FALSE;
}
void funcA();
void UseA()
{
if (lock())
{
funcA();
unlock();
}
}
and when you want begin rundown - once call
bStop = TRUE; unlock();
how you can see lock function is interlocked increment gLockCount on 1 but only if it not 0.
in kernel mode you can call instead
EX_RUNDOWN_REF gRunRef;
void UseA()
{
if (ExAcquireRundownProtection(&gRunRef))
{
funcA();
ExReleaseRundownProtection(&gRunRef)
}
}
and on place final unlock - ExWaitForRundownProtectionRelease
some more complex and scalable implementation of rundown-protection:
#define RUNDOWN_INIT_VALUE 0x80000000
#define RUNDOWN_COMPLETE_VALUE 0
class __declspec(novtable) RUNDOWN_REF
{
LONG _LockCount;
protected:
virtual void RundownCompleted() = 0;
public:
BOOL IsRundownBegin()
{
return 0 <= _LockCount;
}
void Reinit()
{
if (InterlockedCompareExchange(&_LockCount, RUNDOWN_INIT_VALUE, RUNDOWN_COMPLETE_VALUE) != RUNDOWN_COMPLETE_VALUE)
{
__debugbreak();
}
}
RUNDOWN_REF()
{
_LockCount = RUNDOWN_INIT_VALUE;
}
BOOL AcquireRundownProtection()
{
LONG Value = _LockCount, NewValue;
for ( ; Value < 0; Value = NewValue)
{
NewValue = InterlockedCompareExchange(&_LockCount, Value + 1, Value);
if (NewValue == Value) return TRUE;
}
return FALSE;
}
void ReleaseRundownProtection()
{
if (RUNDOWN_COMPLETE_VALUE == InterlockedDecrement(&_LockCount))
{
RundownCompleted();
}
}
void BeginRundown()
{
if (AcquireRundownProtection())
{
_interlockedbittestandreset(&_LockCount, 31);
ReleaseRundownProtection();
}
}
};
and use it like:
class MY_RUNDOWN_REF : public RUNDOWN_REF
{
HANDLE _hEvent;
virtual void RundownCompleted()
{
SetEvent(_hEvent);
}
// ...
} gRunRef;
void UseA()
{
if (gRunRef.AcquireRundownProtection())
{
funcA();
gRunRef.ReleaseRundownProtection();
}
}
and when you want stop:
gRunRef.BeginRundown();// can be safe called multiple times
// wait on gRunRef._hEvent here
interesting that in kernel exist else one (more old - from win2000, when rundown protection from xp) api Remove Locks. it do almost the same. different only in internal implementation and usage. with remove locks code will be look like this:
IO_REMOVE_LOCK gLock;
void UseA()
{
if (0 <= IoAcquireRemoveLock(&gLock, 0))
{
funcA();
IoReleaseRemoveLock(&gLock, 0);
}
}
and when we want stop - call
IoAcquireRemoveLock(&gLock, 0);
IoReleaseRemoveLockAndWait(&gLock, 0);
my first code spinet by implementation near remove locks implementation, when second near rundown-protection implementation. but by sense both do the same

How to retrieve data from a std::list containing boost::shared_ptr

I need helping trying to retrieve data held in a std::list<boost::shared_ptr<boost::any>>
I working on a Singleton Controller class with a private std::list. Client class(es) will be able to add/remove/edit concrete class objects to be used by the program through this Controller class.
The reason for using boost::shared_ptr is because I assign a unique objID to each concrete class created. Once instance objs are added to controller, user will be able to search and remove objs later. The Add(....) and Remove(...) overloaded methods for each concrete class work fine.
I am now trying to create getObject(int index) & setObject(int index) methods but can't seem to figure out how to cast the returned pointer to a Concrete class.
Please advise.
My current code:
//===============================================================
//Singleton.h controller class
private:
static Singleton *mgr;
typedef boost::shared_ptr<boost::any> Shapes_Ptr;
//private static list
static std::list<Shapes_Ptr> shapes;
public:
const Shapes_Ptr getObject( int index) const; //Return Shape
Shapes_Ptr EditObject( const int index ); //Edit Shape
Info(); //Prints contents of instance to console screen
//===============================================================
//Singleton.cpp
//Return Shape
const Shapes_Ptr getObject( int index) const
{
int cc = 0;
if ( (int)shapes.size() > ZERO && index < (int)shapes.size() )
{
list<Shapes_Ptr>::const_iterator i;
for ( i = shapes.begin(); i != shapes.end(); ++i )
{
if ( cc == index )
{
return (*i);
break;
}
else { ++cc; }
}//for-loop
}
}
//Edit Shape
Shapes_Ptr EditObject( const int index )
{
//same code as getObject()...
}
//===============================================================
//main.cpp
Singleton *contrl= Singleton::Instance();
int main()
{
for ( int i=0; i< 2; ++i )
{
contrl->CreateObject(Box2D() );
}
for ( int i = contrl->Begin(); i< contrl->End(); ++i )
{
if ( boost::any_cast<boost::any> (contrl->getObject(i)).type() == typeid(Physics::Box2D) )
{
//Code compiles but crashes on launch....
any_cast<Box2D> (contrl->getObject(i) ).Info(); // <== ERROR CODE
}
//More if checks for other Concrete classes....
}
}
Putting aside whatever the particular issue with your current code is, I think there is an issue with your design.
You have this Singleton manager class that acts as a sort of pool and also as you say assigns unique IDs to each object so they can be found later. But you know what lets code find objects? Pointers! If you use a normal pool, one per type hierarchy (so no more Boost Any), you may find it just as useful, and there will be less nasty if/else typeid-checking code (which everyone would agree is not a good use of RTTI, aside from being poor OOP).
So, what do you say? Chuck this, and use Boost Pool if you want something to allocate your objects from a central place, and use pointers as your unique IDs, thus avoiding lookups along the way.

Comparison method violates its general contract! Java 7 only

I know this has been an issue for a while now, and checked all previously answers I could get, but still this one doesn't work.
The object 'crew' represents crewmembers with ranks and other items. The comparison should be made by comparing 'assigned_rank', an int value, and if this value is equal in both instances, then 'is_trainer', a boolean, should make the difference.
This method worked great as long as it was running with java < 7. But since Java 7 I keep getting this one:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:714)
at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:451)
at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:376)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:182)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at dormas_flightlog.Query.getCrew(Query.java:714)
Here is the source, where some potentially dangerous parts have allready been out-commented, but it still does not work:
public class crew implements Serializable, Comparable<crew> {
private static final long serialVersionUID = 36L;
private int flightID = 0;
private int assigned_rank = 25;
private boolean is_trainer = false;
...
#Override
public int compareTo(crew him) {
int myRank = this.getAssigned_rank();
int hisRank = him.assigned_rank;
if (this == him) {
return 0;
}
if (myRank > hisRank) {
return 1;
}
if (myRank < hisRank) {
return -1;
}
if (myRank == hisRank) {
// if (is_trainer && !o.is_trainer) {
// i = 1;
// }
// if (!is_trainer && o.is_trainer) {
// i = -1;
// }
// if (is_trainer && o.is_trainer) {
// i = 0;
// }
// if (!is_trainer && !o.is_trainer) {
// i = 0;
// }
return 0;
}
return 0;
}
#Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + this.assigned_rank;
hash = 31 * hash + (this.is_trainer ? 1 : 0);
return hash;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
int myRank = this.getAssigned_rank();
int hisRank = 0;
if (o instanceof crew) {
crew him = (crew) o;
hisRank = him.assigned_rank;
} else {
return false;
}
if (myRank > hisRank) {
return false;
}
if (myRank < hisRank) {
return false;
}
if (myRank == hisRank) {
// if (is_trainer && !o.is_trainer) {
// i = 1;
// }
// if (!is_trainer && o.is_trainer) {
// i = -1;
// }
// if (is_trainer && o.is_trainer) {
// i = 0;
// }
// if (!is_trainer && !o.is_trainer) {
// i = 0;
// }
return true;
}
return false;
}
}
Implementing equals() was just a try to solve this problem. The given exception comes with or without equals(). I cannot see how the compareTo-method violates its contract. Any help is greatly appreciated....one day this code has to work with java 7 and I don't know how...
Thanks
see this:
From http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source
Area: API: Utilities Synopsis: Updated sort behavior for Arrays and
Collections may throw an IllegalArgumentException
Description: The sorting algorithm used by java.util.Arrays.sort and
(indirectly) by java.util.Collections.sort has been replaced. The new
sort implementation may throw an IllegalArgumentException if it detects
a Comparable that violates the Comparable contract. The previous
implementation silently ignored such a situation. If the previous
behavior is desired, you can use the new system
property java.util.Arrays.useLegacyMergeSort, to restore previous
mergesort behavior.
Nature of Incompatibility: behavioral
RFE: 6804124
For more detailed info, see the bug database reference here.
maybe you just have NaN values which you compare through Collections.sort(...), this has been a problem to me and I got that exception even having right implementation of compare(obj1, obj2) method! Check that!
I was able to solve this error cause it was a bug in jdk7.
here I found the solution:
"Comparison method violates its general contract!" - TimSort and GridLayout
Basically i just had to add the
JAVA_OPTS="$JAVA_OPTS -Djava.util.Arrays.useLegacyMergeSort=true"
to my jboss
Unfortunately, none of the solutions work for Android. TimSort is used deep in Android's ViewGroup relating to addChildrenForAccessibility that shows up under Java 7 & 8. No user code is involved in any comparison.
From other reports, it is related to having RelativeLayout with overlapping items as is commonly done. For example, a TextView that appears over an Image, or two items at the same location, where you only set one visible at a time.
https://code.google.com/p/android/issues/detail?id=55933
I've not found any way around the bug. You can't set a -Djava option in Android Studio or Eclipse (at least that I could find). Forcing use of Java 1.6 should work, but doesn't. Seems like Amazon's newer Fire tablets and phones are far more sensitive to this bug than other devices.
There are rumors Java 9 will have a fix such as a run-time option that works, but with a bug that's been around for years, I have doubts it will ever be fixed - especially considering the animosity between Oracle and Google. Any yes, perhaps the bug is really deep in the Android code and should be fixed there. With more than a billion devices out there, that's not a viable solution for all the existing devices.

Resources