So i'm digging into what is complex java for me. I'm looking at multithreading and i was wondering about when you send the same instance of an object to two different threads then assign that instance of the object to two separate instance variables in the two threads. Does java see this as the same instance of the original object? Is that only for Threads?
For example: in my driver
SharedCell share = new SharedCell();
Producer p = new Producer(accessCount, share);
Consumer c = new Consumer(accessCount, share);
and in the threads:
public Producer(int accesses, SharedCell cell) {
super("Producer");
this.accesses = accesses;
this.cell = cell;
}
and
public Consumer(int accesses, SharedCell cell) {
super("Consumer");
this.accesses = accesses;
this.cell = cell;
}
where the run method in Producer changes the value of a variable in a SharedCell object
and the run method in Consumer accesses that variable. these are supposed to switch off doing so.
So does the cell in Consumer and Producer reference the same object that the driver sent them?
Objects are reference type in java, as in most languages, which means yes in your example both consumer and producer point to the same object in memory. And no, it's not only for threads. Even in single thread they'll have reference to the same object.
Related
I have come to really appreciate the benefits of using objects to deploy a given application within the DigitalMicrograph environment via the DMS language. The object-oriented approach opens the door to the use of reusable design patterns involving collaborating objects, e.g. Model-View-Controller (MVC). However, objects within DM seem to be highly volatile due to the use of automatic reference counting to manage their life cycles. In order for an MVC trio, or any other set of collaborating objects, to stay alive long enough to be useful, at least one of them must be rooted in a non-volatile object managed by the DM application. So far, the only such objects I have come across within DM are those based on the UIFrame class (i.e. modeless dialogs and UI palettes). For MVC implementations, this works out fine since it makes sense to implement the View as a UIFrame object. It's just a bit unconventional in that the View object becomes the root object that keeps the MVC trio alive and functioning. Normally it is the Controller object that is rooted in the application and manages the Model and View objects. But what about design patterns that do not involve UI? Is there any (acceptable) way to give a set of collaborating objects persistence without rooting them in a UIFrame object? Are there other application-rooted object types that can serve this purpose? I assume setting up a reference cycle would not be an acceptable approach due to the inevitable risk of memory leaks.
The third, and by far the best and cleanest solution is to launch your object as a 'listener' to some event. As you are looking for an object which should stay in scope as long as DigitalMicrograph is open, its possibly best to listen to the application itself. By listening for the "about_to_close" message you also get the ideal handle to properly release all resources before shutdown. The code is the following:
From my 3 answers this is the one I would use. (The others should just illustrate options.)
class MyPermanentObject
{
MyPermanentObject( object self ) { result("created MyPermanentObject :"+self.ScriptObjectGetID()+"\n");}
~MyPermanentObject( object self ) { result("killed MyPermanentObject :"+self.ScriptObjectGetID()+"\n");}
void DeInitialize( object self, number eventFlags, object appObj )
{
OKDialog( "The application is closing now. Deinitialize stuff properly!" );
}
}
{
object listener = Alloc( MyPermanentObject )
ApplicationAddEventListener( listener, "application_about_to_close:DeInitialize" )
}
I can think of various ways to get this persistence, but the one which jumped to mind first was to launch one object into a background thread, like in the example below. The actual background thread can check every so often if the object should still remain, and by sharing the object ID with the outside world, other objects (which don't have to be persistent) can access the "anchored" object.
A word of warning though: If you keep things in memory like this, you have to be careful when closing DigitalMicrograph. If the object hangs on to some items DM wants to destroy, you might see errors or crashes at the end.
// This is the object "anchored". It will remain in memory, because we launch it on a separate thread.
// On this thread, it loops until a variable is set to false (or until SHIFT is pressed)
Class IPersist : Thread
{
number keepme
IPersist( object self ) { result("created IPersist:"+self.ScriptObjectGetID()+"\n");}
~IPersist( object self ) { result("killed IPersist:"+self.ScriptObjectGetID()+"\n\n\n\n");}
void CallFromOutside( object self ) { Result( "\t IPersist can be used!\n" ); }
void StopFromOutside( object self ) { keepme = 0; }
void RunThread( object self )
{
keepme = 1
Result( "\t Called once at start.\n")
While( keepme && !ShiftDown() ) yield()
Result( "\t Finished.\n")
}
}
// Just and example class used to access the 'anchored' object
Class SomethingElse
{
number keepID
SomethingElse( object self ) { result("created SomethingElse:"+self.ScriptObjectGetID()+"\n");}
~SomethingElse( object self ) { result("killed SomethingElse:"+self.ScriptObjectGetID()+"\n");}
void SetKeepID( object self, number id ) { keepID = id; }
void CallOut( object self )
{
result( "SomethingElse object is accessing CallOut...\n" )
object p = GetScriptObjectFromID( keepID )
if ( p.ScriptObjectIsValid() )
{
p.CallFromOutside()
}
}
void CallStop( object self )
{
result( "SomethingElse object is accessing CallOut...\n" )
object p = GetScriptObjectFromID( keepID )
if ( p.ScriptObjectIsValid() )
{
p.StopFromOutside()
}
}
}
// Main script. Create object on separate thread. Then feed it's ID as "weak reference" into the second object.
{
object ob = Alloc(IPersist)
ob.StartThread()
object other = Alloc(SomethingElse)
other.SetKeepID( ob.ScriptObjectGetID() )
other.CallOut()
If ( TwoButtonDialog( "You can either stop IPerstis now, or by pressing SHIFT later.", "Stop now", "later" ) )
other.CallStop()
}
An alternative way would be to have two objects keep references of each other. This is a deadlock-situation one would normally rather avoid, but for the purpose of anchoring it works as well. No object can go out of scope until you release one on purpose.
Again, it is your responsibility to 'release' things when you want a proper shutdown of the system.
The code for the deadlock-situation is rather slim:
class SelfLock
{
object partner
SelfLock( object self ) { result("created SelfLock:"+self.ScriptObjectGetID()+"\n");}
~SelfLock( object self ) { result("killed SelfLock:"+self.ScriptObjectGetID()+"\n");}
void SetPartner(object self, object p) { partner = p; }
void ReleasePartner(object self) { partner = NULL; }
}
{
object p1 = Alloc(SelfLock)
object p2 = Alloc(SelfLock)
p1.SetPartner(p2)
p2.SetPartner(p1)
if ( TwoButtonDialog( "Release partner", "Yes", "No keep locked" ) )
p1.ReleasePartner()
}
I have a setup with a main model (QStandardModel), a proxy model which changes the output of the DisplayRole, and a separate tableview displaying each model. Inside the main model data is a user role that stores a pointer to another QObject which is used by the proxy model to get the desired display value.
I'm running into problems when the object pointed to by that variable is deleted. I am handling deletion in the main model via the destroyed(QObject*) signal. Inside the slot, I search through the model looking for any items that are pointing to the object and delete the reference.
That part works fine on its own but I also have connected to the onDataChanged(...) signal of the proxy model, where I call resizeColumnsToContents() on the proxy model. This then calls the proxy's data() function. Here I check to see if the item has a pointer and, if it does, get some information from the object for display.
The result of all this becomes:
Object about to be deleted triggers destroyed(...) signal
Main model looks for any items using the deleted object and calls setData to remove the reference
Tableview catches onDataChanged signal for the proxy model and resizes columns
Proxy model's data(...) is called. It checks if the item in the main model has the object pointer and, if so, displays a value from the object. If not, it displays something else.
The problem is, at step 4 the item from the main model apparently still hasn't been deleted; the pointer address is still stored. The object the pointer was referencing, though, has been deleted by this point resulting in a segfault.
How can I fix my setup to make sure the main model is finished deleting pointer references before the proxy model tries to update?
Also, here is pseudo-code for the relevant sections:
// elsewhere
Object *someObject = new QObject();
QModelIndex index = mainModel->index(0,0);
mainModel->setData(index, someObject, ObjectPtrRole);
// do stuff
delete someObject; // Qt is actually doing this, I'm not doing it explicitly
// MainModel
void MainModel::onObjectDestroyed(QObject *obj)
{
// iterating over all model items
// if item has pointer to obj
item->setData(QVariant::fromValue(NULL), ObjectPtrRole));
}
// receives onDataChanged signal
void onProxyModelDataChanged(...)
{
ui->tblProxyView->reseizeColumnsToContents();
}
void ProxyModel::data(const QModelIndex &index, int role) const
{
QModelIndex srcIndex = mapToSource(index);
if(role == Qt::DisplayRole)
{
QVariant v = sourceModel()->data(srcIndex, ObjectPtrRole);
Object *ptr = qvariant_cast<Object*>(v);
if(ptr != NULL)
return ptr->getDisplayData();
else
return sourceModel->data(srcIndex, role);
}
}
The problem is ptr is not NULL, but the referenced object is deleted, at the time ProxyModel::data(...) is called so I end up with a segfault.
To avoid dangling pointer dereferences with instances of QObject, you can do one of two things:
Use object->deleteLater - the object will be deleted once the control returns to the event loop. Such functionality is also known as autorelease pools.
Use a QPointer. It will set itself to null upon deletion of the object, so you can check it before use.
The Daemons and Services Programming Guides tells that it is possible to return a proxy object through an open XPC connection, even as a reply block parameter.
Passing an Object By Proxy
Most of the time, it makes sense to copy objects and send them to the other side of a connection. However, this is not always desirable. In particular:
If you need to share a single instance of the data between the client application and the helper, you must pass the objects by proxy.
If an object needs to call methods on other objects within your application that you cannot or do not wish to pass across the connection (such as user interface objects), then you must pass an object by proxy—either the caller, the callee (where possible), or a relay object that you construct specifically for that purpose.
The downside to passing objects by proxy is that performance is significantly reduced (because every access to the object requires interprocess communication). For this reason, you should only pass objects by proxy if it is not possible to pass them by copying.
You can configure additional proxy objects similarly to the way you configured the remoteObjectInterface property of the initial connection. First, identify which parameter to a method should be passed by proxy, then specify an NSXPCInterface object that defines the interface for that object.
First questions come: how should the object to be passed by proxy be defined? As an object conforming to NSXPCProxyCreating protocol? Should remoteObjectProxy and remoteObjectProxyWithErrorHandler: method be implemented then?
An example follows, that is not clear at all to me. In particular I don't understand where should I call the NSXPCInterface method (setInterface:forSelector:argumentIndex:ofReply:) to whitelist the parameter as a proxy: in the XPC service code or in the host?
The first parameter to a method is parameter 0, followed by parameter 1, and so on.
In this case, the value NO is passed for the ofReply parameter because this code is modifying the whitelist for one of the parameters of the method itself. If you are whitelisting a class for a parameter of the method’s reply block, pass YES instead.
So the question is: can anybody provide me with a clear tutorial on how to return an object as a proxy in a block reply of a XPC method call?
I can answer my own question now: to return an object as a proxy in a block reply of a XPC method call, one should call the setInterface:forSelector:argumentIndex:ofReply: method both:
in the XPC service's endpoint, where the exportedInterface is declared
in the host, where the remoteObjectInterface is declared
I.e, common code:
// common (service/host) protocol definition
#protocol Service
#end
#protocol ServiceFactory
-(void)connectToNewService: (void (^)(id<Service>)reply;
#end
In the XPC Service:
// Implement the one method in the NSXPCListenerDelegate protocol.
-(BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection*)newConnection {
NSXPCInterface *serviceFactoryInterface =[NSXPCInterface interfaceWithProtocol:#protocol(ServiceFactory)];
NSXPCInterface *serviceInterface =[NSXPCInterface interfaceWithProtocol:#protocol(Service)];
// connection has to be returned as proxy, not as a copy
[serviceFactoryInterface setInterface: serviceInterface
forSelector: #selector(connectToNewService:)
argumentIndex: 0
ofReply: YES];
newConnection.exportedInterface = serviceFactoryInterface;
newConnection.exportedObject = self;
[newConnection resume];
return YES;
}
In the host code:
// in the host
- (void)openNewService
{
NSXPCConnection *xpcConnection = [[NSXPCConnection alloc] initWithServiceName:#"eu.mycompany.servicefactory"];
NSXPCInterface *serviceFactoryInterface =[NSXPCInterface interfaceWithProtocol:#protocol(ServiceFactory)];
NSXPCInterface *serviceInterface =[NSXPCInterface interfaceWithProtocol:#protocol(Service)];
// connection has to be returned as proxy, not as a copy
[serviceFactoryInterface setInterface: serviceInterface
forSelector: #selector(connectToNewService:)
argumentIndex: 0
ofReply: YES];
xpcConnection.remoteObjectInterface = serviceFactoryInterface;
[xpcConnection resume];
[[xpcConnection remoteObjectProxy] connectToNewService:^(id<Service> newService) {
// here a newService is returned as NSXPCDistantObject <Service>*
[xpcConnection invalidate];
}];
}
I am trying to learn WCF with this example
http://www.codeproject.com/Articles/39143/C-WCF-Client-Server-without-HTTP-with-Callbacks-Ma
Also trying to extend the functionality on the server by adding mutual exclusion with multiple clients.
I am basically trying to have a global array of numbers and a function(which has been exposed with an Operationcontract) that can access this array.But only one client is allowed to access the array at a time.
Can someone point me in the right direction by adding a simple function with a mutual exclusion lock?
Depending on what exactly you want to do, how about putting a lock around the function accessing your array (maybe event put your array into a singleton).
Then you could have
class SingletonClassForYourArray {
object aLock = new object();
int yourArray;
private SingletonClassForYourArray instance;
public SingletonClassForYourArray GetInstance()
{
// normal singleton init of instance on demand
}
int [] YourArray
{
get
{
lock(aLock)
{
return yourArray;
}
}
}
}
This would be the easiest way to have only one client access the array. All clients without the lock will have to wait in turn (fairness not guaranteed). Be careful as this may result in timeouts if clients have to wait to long.
I have a WCF service hosted in a Windows Service (running under Local System). I am running a System.Timer inside it. The Operation o1, that initializes the Timer, is declared over a http endpoint over webHttpBinding.
I enabled tracing for System.ServiceModel and from the .svcLog file I checked the Listen Duration for the Operation o1. It shows that, after running for approx 20 hours the Listening at the http endpoint just stops.
I think the this due to the fact that no incoming message arrived at that endpoint. The issue here is with the Listening coming to a stop, my timer(which was initialized inside that particular Operation o1) also stops!
Is there a recommended way to keep the Listener, and hence the timer, up for long durations?
Can we periodically ping the o1 Operation to keep it in memory?
Also, my timer variable that I initialize inside the Operation o1 is an instance variable, isn't this variable expected to be in memory (the WCF being a Singleton) even if the Listener closes??
Thanks so much.
Code Exceprts-
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class SchedulerWindows : ISchedulerWindows
{
///.........all instance variables.....
DataTimer timer = null; /**DataTimer wraps a System.Timers timer variable**/
public List<DataTimer> timersInService = new List<DataTimer>();
public ISchedulerWindows.o1(string s1, string s2, /*********/)
{
//..........//
timer = new DataTimer();
}
}
public class DataTimer
{
/****Newly introduced System.Threading.Timer, previously I was using System.Timers.Timer which was dying****/
public System.Threading.Timer thTimer;
private static readonly object dbAccessLock = new object();
private static readonly object thCallbackLock = new object();
public DataTimer()
{
}
public DataTimer(/************/)
{
TimerCallback timerDelegate = new TimerCallback(this.WorkMethod);
EventLogLogger l = new EventLogLogger();
//l.LogMessage("setting up timer ");
thTimer = new Timer(this.WorkMethod, null, 0, period);
}
...
}
EDIT: Changing to System.Threading namespace from System.Timers namespace AND increasing the timed interval fixed it for me. The timer variable doesn't disappear anymore.
The most likely cause for your issue is InstanceContextMode. If you want your service instance to always be in memory you should use Single. You probably have PerSession or PerCall and that would explain why your timer is disappearing. You mention that your service is singleton but the symptoms are very suspicious. The service instance stays in memory until you shutdown host.
[ServiceBehavior(
ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.Single
)]
From WCF instance management:
The singleton service lives forever, and is only disposed of once the
host shuts down. The singleton is created exactly once when the host
is created.
EDIT: You probably checked that windows service is still running when your listener stops listening and timer disappears. It would also make sense to see if ServiceHost itself stays in memory. You can also put some logging in ServiceHosts 'Closing', 'Closed' and 'Faulted' event handlers.
EDIT 2:
If your timer is disappearing than you should look at how you allocate it. It most likely gets garbage collected. You have to declare it as an instance field that is reachable from live objects. Make it static to be absolutely sure. You do it for DataTimer but it is not clear how the timer is declared and allocated inside DataTimer. Post some code please.
EDIT 3:
You should not create timers in the operation. What happens if operation get called more than once? What happens to the old timer? I don't see how you close/dispose it. You also seem to have two constructors for DataTimer. One of them is doing nothing. And on top of that you have separate list of timers. This is a bit convoluted. Please isolate the problem and maybe post new code after that.
I've not come across this issue specifically - however, if you just want the timer running while the service is running why not make it static. Then your instance context mode and instance lifetime won't affect your functionality.