/* Destroy * destroy */ LIB_EXPORT rc_t CC KCipherManagerDestroy ( KCipherManager *self ) { rc_t rc = 0; if ( self == NULL ) rc = RC ( rcKrypto, rcMgr, rcDestroying, rcSelf, rcNull ); else { if (self == singleton . ptr) { KCipherManager * reread; reread = atomic_test_and_set_ptr (&singleton, NULL, self); /* ignore results: just going for guaranteed atomicity though might not need it */ ( void ) reread; } /* no return value */ KRefcountWhack (&self->refcount, kciphermanager_classname); rc = KLockRelease (self->lock); free (self); } return rc; }
/* Make * we have a shared singleton for the cipher manager * first call actually makes the managerblo * subsequent calls get added references */ LIB_EXPORT rc_t CC KCipherManagerMake (KCipherManager ** mgr) { rc_t rc = 0; if (mgr == NULL) return RC (rcKrypto, rcMgr, rcConstructing, rcSelf, rcNull); *mgr = NULL; make_race_retry: if (singleton . ptr) { rc = KCipherManagerAddRef (singleton.ptr); if (rc == 0) { *mgr = singleton . ptr; return 0; } } else { KCipherManager * self; rc = KCipherManagerAlloc (&self); if (rc == 0) { rc = KCipherManagerInit (self); if (rc == 0) { KCipherManager * reread; reread = atomic_test_and_set_ptr (&singleton, self, NULL); if (reread) { KCipherManagerDestroy (self); goto make_race_retry; } *mgr = self; return 0; } else { KCipherManagerDestroy (self); } } } return rc; }
static rc_t CC ReportRelease ( void ) { rc_t rc = 0; Report *prev_report, *cur_report; cur_report = report_singleton . ptr; do { prev_report = cur_report; cur_report = atomic_test_and_set_ptr ( & report_singleton, NULL, prev_report ); } while ( cur_report != prev_report ); if ( cur_report != NULL ) { /* cleanup */ VTableRelease ( cur_report -> table ); VDatabaseRelease ( cur_report -> db ); VDBManagerRelease ( cur_report -> mgr ); memset ( cur_report, 0, sizeof * cur_report ); } return rc; }