c++ - In which order should I send callback() & notify waiters? -


I have a class through which I provide some services asynchronously (same call to synchronous Can be made) When an object of this class is requested (operator says) the operation starts in a separate thread. Other object operators can register on the object's information so that the operation-indented () method can be called on this object when the operation is finished. Waiting for the operator object () and other objects can also wait for this operation to complete.

At the end of the operation the code is very low:

  _opEndedMutex.lock (); _thereIsOngoingOp = false; _opEndedCondition.notify_all (); _opEndedMutex.unlock (); // no more calls after the notification m_spNotificationManager-> Operationed ();  

and wait () function is as follows:

  boost :: unique_lock & lt; Boost :: mutex & gt; Lock (_opEndedMutex); While (_thereIsOngoingOp) {_opEndedCondition.wait (_opEndedMutex); }  

The problem is about resource management, it's a C ++ class, so when the end of the operation shows that the user of this class can remove the operator object (if any If there is an active operation then the district waits for completion). At the end of the operation, either by waiting or waiting for the notification. So if I remove _opEndedCondition.notify_all () the first and the user operator object (called to call the OperationEnded), because m_spNotificationManager is removed, it may crash while trying. And if OperationEnded () can choose to call first and the user deletes the operator object during this call then it may crash while attempting to access _opEndedMutex, _thereIsOngoingOp and _opEndedCondition.

The first thing that comes to mind as one of my solutions is to protect two calls with a new mute. It does not look very good because I think that if a new mute has been introduced and what if the operation starts a new operation from user coordination in notification (notified) I am not sure that wait How to use new mutes.

Note 1: This API is used in our own company and other companies' applications. So I can not get rid of any of the synchronization mechanisms.

Note 2: .. If I modified the original code, variable and method name then there may be writing error, but this idea should be clarified

edit1:

operator object generated through a factory Live in a shared library and then come in front of the outside world through the interface. Therefore, the normal life of the operator object will be:

  IOperator * op = factory: getNewOperator (); // op op-> Working with the release () / / It removes and deletes an object  

Also keep in mind that operator objects are reusable client code a new operator object it several times You can use and delete it at the end.

You have some of its solutions:

  • Specialize the operation object from special This would mean that in the customer code, you can now remove the object, but a std :: shared_ptr is set to nullptr, and no one cares when the object is actually removed.

  • You can apply limited garbage collection, on a timer delay: if you receive the code> OperationEnded () notification in the customer code, you indicate To pick and when to place on a line with a timestamp, the object was added together. The queue is an active object that wakes up on a timer, takes the current time, and if the timestamp is (assuming) at least five seconds than the current time, it removes it.

  • You can allocate and assign to one by using the operation class. When an object is not used, it is not actually removed, but kept in the pool as a free (recycled) object

  • You You can create a life-time-manager for the object, which will remove your operation object and then send the notification.

  • You can delete your 'Operation-indented' function call by ; Finally; After that, when you receive the notification, apply the client code to set the pointer to zero; Although such solutions are brittle and it is possible that with your implementation, it changes the problem into different codes.

  • Finally, you can apply a custom combination of all these.


Comments