1 / 21

RAII

RAII. Resource Allocation IS initialization. Agenda. The RAII pattern Examples Exception safety. The problem. new/delete aquire/unaquire connect/disconnect lock/unlock subscribe/unsubscribe register/unregister open/close. The problem. Need to match call pairs

valdeza
Download Presentation

RAII

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. RAII Resource Allocation IS initialization

  2. Agenda • The RAII pattern • Examples • Exception safety

  3. The problem • new/delete • aquire/unaquire • connect/disconnect • lock/unlock • subscribe/unsubscribe • register/unregister • open/close

  4. The problem Need to match call pairs Need to know if a resource is initialized

  5. The solution Link call pair to an object’s life time • Constructor: Aquire resource • Destructor: Release resource

  6. Stackbased example void monkey_func() { ... MyResource res; // May throw ... do_stuff(res); ... } // Automatically releases res

  7. Without RAII class Foo { class Listener { virtual void Bar() = 0; }; void subscribe(Listener& l); void unsubscribe(Listener& l); };

  8. Using RAII class Foo { class Listener { virtual void Bar() = 0; }; class SubscriptionToken { SubscriptionToken(Foo& f, Listener& l); }; };

  9. Example usage code class ConstantFooListener : public Foo::Listener { Dummy(Foo& f) : token_(f, *this) {} Foo::SubscriptionToken token_; }

  10. Why the strange acronym? No two-stage initialization class SomeResource { SomeResource(...); bool Initialize(...); };

  11. What are the benefits? • No uninitialized resources • Close impossible to mismatch call pairs • Exception safe!

  12. Sidetrack: Exception safe code How to implement commit/rollback

  13. The problem Operation • Subsequent calls which might throw • Some steps need to be undone The whole operation should succeed or fail

  14. Example problem prepare_something(); possibly_throwing_call_1(); possibly_throwing_call_2(); rollback_preparation(); rollback_call_1();

  15. Naive approach prepare_something(); try { possibly_throwing_call_1(); try { possibly_throwing_call_2(); } catch (...) { rollback_call_1(); rollback_preparation(); throw; } } catch (...) { rollback_preparation(); throw; }

  16. Problem with naive approach • Error-prone to write • Difficult to read • Difficult to change • Poor scalability

  17. A better solution Suggestions?

  18. A RAII similar solution Half of RAII, just the cleanup part Object whose destructor rollbacks change Commit by dismissing rollback

  19. A general object class ScopeGuard { ScopeGuard(const boost::function<void()>& rollback) : mRollBack(rollback) {} ~ScopeGuard() { if (mRollBack) mRollBack(); } void Dismiss() { mRollback = boost::function<void()>(); } private: boost::function<void()> mRollback; };

  20. ScopeGuard example prepare_something(); ScopeGuard preparation_guard(rollback_preparation); possibly_throwing_call_1(); ScopeGuard call_1_guard(rollback_call_1); possibly_throwing_call_2(); // Commit preparation_guard.Dismiss(); call_1_guard.Dismiss();

  21. Re-cap

More Related