//.............................................................................. // // This file is part of the Jancy toolkit. // // Jancy is distributed under the MIT license. // For details see accompanying license.txt file, // the public copy of which is also available at: // http://tibbo.com/downloads/archive/jancy/license.txt // //.............................................................................. // Jancy provides a convenient way of deterministic resource release using // 'disposable' storage class. // C++ features absolutely the best approach to handling resources -- RAII. // It means resources are aquired during object construction and released // during destruction. // Classes in Jancy may have destructors, too. Therefore, all the necessary // resource release operations (e.g. closing files, dropping connections, // releasing locks etc) could be placed in destructors. The problem is, // destructors in GC world are not called deterministically. First the // Garbage Collector must decide it needs to free unreachable objects; then the // mark stage must complete. Only then the destructor of an about-to-be-freed // object will be called. Keeping resources acquired for that long is simply // not acceptable. // To remedy this problem, Jancy features duck-typed Disposable-pattern. All // the variables (classes, structs or unions) declared using 'disposable' // storage will have their 'dispose' method called upon exiting the scope. This // method will be called no matter which exit route is taken, be it normal // control flow, return, break, throw, other exception(s) etc. //.............................................................................. class Resource { protected int m_resource; construct (int resource) { if (resource) printf ("acquire resource #%d...\n", resource); m_resource = resource; } destruct () { release (); } release () { if (!m_resource) return; printf ("release resource #%d...\n", m_resource); m_resource = 0; } alias dispose = release; } //.............................................................................. foo () { printf ("foo is about to throw...\n"); throw; } // entry point int main () { printf ("main ()\n"); disposable Resource resource1 (1); disposable Resource resource2 (2); Resource resource3 (3); // this resource will be released non-deterministically foo (); return 0; catch: printf ("exception caught in main\n"); return -1; } //..............................................................................