Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

RAII and ScopeGuard

6,225 views

Published on

Published in: Technology, Education
  • Be the first to comment

RAII and ScopeGuard

  1. 1. “RESOURCE ACQUISITION IS INITIALIZATION” Andrey Dankevich April, 20131 4/18/2013
  2. 2. What is a resource? • Memory • Handles • Locks • Sockets • Threads • Temp files • …2 4/18/2013
  3. 3. What is a resource? “Resource” is anything that follows this pattern!3 4/18/2013
  4. 4. So what’s the problem? Real code might have different points at which the resource should be released:4 4/18/2013
  5. 5. Resources and errors void f(const char* p) { FILE* f = fopen(p,"r"); // acquire // use f fclose(f); // release }5 4/18/2013
  6. 6. Resources and errors // naïve fix: void f(const char* p) { Is this code really FILE* f = 0; try { safer? f = fopen(p, "r"); // use f } catch (…) { // handle every exception if (f) fclose(f); throw; } if (f) fclose(f); }6 4/18/2013
  7. 7. RAII// use an object to represent a resourceclass File_handle { // belongs in some support library FILE* p; public: File_handle(const char* pp, const char* r) { p = fopen(pp,r); if (p==0) throw File_error(pp,r); } File_handle(const string& s, const char* r) { p = fopen(s.c_str(),r); if (p==0) throw File_error(s,r); } ~File_handle() { fclose(p); }};7 4/18/2013
  8. 8. Stack lifetime semanticsIn C++ the only code that can be guaranteed to beexecuted after an exception is thrown are the destructorsof objects residing on the stack.  Deterministic  Exception-safe void f() { A a; throw 42; } // ~A() is called8 4/18/2013
  9. 9. LIVE DEMO http://ideone.com/enqHPr9 4/18/2013
  10. 10. .NET• Java, C# and Python, support various forms of the dispose pattern to simplify cleanup of resources.• Custom classes in C# and Java have to explicitly implement the Dispose method. using (Font font1 = new Font("Arial", 10.0f)) { byte charset = font1.GdiCharSet; }10 4/18/2013
  11. 11. .NET• Java, C# and Python, support various forms of the dispose pattern to simplify cleanup of resources.• Custom classes in C# and Java have to explicitly implement the Dispose method. { Font font1 = new Font("Arial", 10.0f); try { byte charset = font1.GdiCharSet; } finally { if (font1 != null) ((IDisposable)font1).Dispose(); }11 } 4/18/2013
  12. 12. .NET - Examples Working with temp files: class TempFile : IDisposable { public TempFile(string filePath) { if (String.IsNullOrWhiteSpace(filePath)) throw new ArgumentNullException(); this.Path = filePath; } public string Path { get; private set; } public void Dispose() { if (!String.IsNullOrWhiteSpace(this.Path)) { try { System.IO.File.Delete(this.Path); } catch { } this.Path = null; } }12 4/18/2013 }
  13. 13. .NET - ExamplesWorking with temp settings values: Check the implementation for AutoCAD settings http://www.theswamp.org/index.php?topic=31897.msg474083#msg474083Use this approach if you need to temporarily change the settings inapplication.13 4/18/2013
  14. 14. Back to C++Many STL classes use RAII: • std::basic_ifstream, std::basic_ofstream and std::basic_fstream will close the file stream on destruction if close() hasn’t yet been called. • smart pointer classes std::unique_ptr for single-owned objects and std::shared_ptr for objects with shared ownership. • Memory: std::string, std::vector… • Locks: std::unique_lock14 4/18/2013
  15. 15. SCOPE GUARD15 4/18/2013
  16. 16. SCOPE GUARD• Original article: http://drdobbs.com/184403758• Improved implementation: http://www.zete.org/people/jlehrer/scopeguard.html• C++ and Beyond 2012: Andrei Alexandrescu - Systematic Error Handling in C++:  video (from 01:05:11) - http://j.mp/XAbBWe  slides ( from slide #31) - http://sdrv.ms/RXjNPR• C++11 implementation: https://github.com/facebook/folly/blob/master/folly/ScopeGuard.h 4/18/2013
  17. 17. SCOPE GUARD vs unique_ptr Real-world example with PTC Creo API: • Resource type: ProReference In fact it’s mere a typedef void* ProReference; • Resource acquire: // Gets and allocates a ProReference containing a // representation for this selection. ProError ProSelectionToReference (ProSelection selection, ProReference* reference); • Resource release: ProError ProReferenceFree (ProReference reference);17 4/18/2013
  18. 18. SCOPE GUARD vs unique_ptr Using std::unique_ptr<>:auto ref_allocator = []( const ProSelection selection ) -> ProReference { ProReference reference; ProError status = ProSelectionToReference(selection, &reference); return reference;};auto ref_deleter = [](ProReference& ref) { ProReferenceFree (ref);};std::unique_ptr <std::remove_pointer<ProReference>::type, decltype(ref_deleter)> fixed_surf_ref ( ref_allocator(sels[0]), ref_deleter );// ref_deleter is guaranteed to be called in destructor18 4/18/2013
  19. 19. SCOPE GUARD vs unique_ptr Using ScopeGuard: ProReference fixed_surf_ref = nullptr; status = ProSelectionToReference ( sels[0], &fixed_surf_ref ); SCOPE_EXIT { ProReferenceFree ( fixed_surf_ref ); }; I LOVE IT!!!19 4/18/2013
  20. 20. http://j.mp/FridayTechTalks20 4/18/2013
  21. 21. Questions?21 4/18/2013

×