update
This commit is contained in:
parent
1f1ad49427
commit
6f050a029e
2496 changed files with 37609 additions and 3031 deletions
131
Task/Singleton/Cache-ObjectScript/singleton.cos
Normal file
131
Task/Singleton/Cache-ObjectScript/singleton.cos
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/// The <CLASS>Singleton</CLASS> class represents a global singleton object that can
|
||||
/// be instantiated by multiple processes. The 'Get' class method is used to obtain
|
||||
/// an in-memory object reference and the 'Set' method is used to save any changes to
|
||||
/// state. See below for an example.
|
||||
///
|
||||
/// <EXAMPLE>
|
||||
/// Set one=##class(Singleton).Get(,.sc)
|
||||
/// Set one.GlobalProperty="Some Value"
|
||||
/// Set sc=one.Set()
|
||||
/// </EXAMPLE>
|
||||
///
|
||||
/// This class can also be extended.
|
||||
Class User.Singleton Extends %SerialObject
|
||||
{
|
||||
|
||||
Property GlobalProperty As %String;
|
||||
|
||||
/// Refer to <LINK href=/AboutConcurrency.html>About Concurrency</LINK> for more details
|
||||
/// on the optional <var>pConcurrency</var> argument.
|
||||
ClassMethod Get(pConcurrency As %Integer = -1, Output pStatus As %Status = {$$$OK}) As Singleton [ Final ]
|
||||
{
|
||||
// check if singleton object already instantiated
|
||||
Set oRef = ""
|
||||
For {
|
||||
Set oRef = $ZObjNext(oRef) If oRef = "" Quit
|
||||
If oRef.%ClassName(1) = ..%ClassName(1) Quit
|
||||
}
|
||||
If $IsObject(oRef) Quit oRef
|
||||
|
||||
// determine what lock needs to be applied
|
||||
If '$IsValidNum(pConcurrency, 0, -1, 4) {
|
||||
Set pStatus = $$$ERROR($$$LockTypeInvalid, pConcurrency)
|
||||
Quit $$$NULLOREF
|
||||
}
|
||||
If pConcurrency = -1 Set pConcurrency = $Xecute("Quit "_..#DEFAULTCONCURRENCY)
|
||||
|
||||
// acquire lock for global singleton object
|
||||
Set lockTO = $ZUtil(115,4), lockOK = 1
|
||||
If pConcurrency<4, pConcurrency {
|
||||
Lock +^CacheTempUser("Singleton", ..%ClassName(1))#"S":lockTO Set lockOK = $Test
|
||||
} ElseIf pConcurrency = 4 {
|
||||
Lock +^CacheTempUser("Singleton", ..%ClassName(1)):lockTO Set lockOK = $Test
|
||||
}
|
||||
If 'lockOK {
|
||||
If pConcurrency = 4 {
|
||||
Set pStatus = $$$ERROR($$$LockFailedToAcquireExclusive, ..%ClassName(1))
|
||||
} Else {
|
||||
Set pStatus = $$$ERROR($$$LockFailedToAcquireRead, ..%ClassName(1))
|
||||
}
|
||||
Quit $$$NULLOREF
|
||||
}
|
||||
|
||||
// retrieve global singleton object and deserialise
|
||||
Set oId = $Get(^CacheTempUser("Singleton", ..%ClassName(1)))
|
||||
Set oRef = ..%Open(oId) //,, .pStatus)
|
||||
If '$IsObject(oRef) Set pStatus = $$$ERROR($$$GeneralError, "Failed to load singleton object.")
|
||||
|
||||
// release temporary lock
|
||||
If (pConcurrency = 1) || (pConcurrency = 2) {
|
||||
Lock -^CacheTempUser("Singleton", ..%ClassName(1))#"S"
|
||||
}
|
||||
|
||||
// singleton object failed to load
|
||||
If $$$ISERR(pStatus) {
|
||||
// release retained lock
|
||||
If pConcurrency = 3 {
|
||||
Lock -^CacheTempUser("Singleton", ..%ClassName(1))#"S"
|
||||
}
|
||||
If pConcurrency = 4 {
|
||||
Lock -^CacheTempUser("Singleton", ..%ClassName(1))
|
||||
}
|
||||
Quit $$$NULLOREF
|
||||
}
|
||||
|
||||
// store concurrency state and return in-memory object reference
|
||||
Set oRef.Concurrency = pConcurrency
|
||||
Quit oRef
|
||||
}
|
||||
|
||||
Method Set() As %Status [ Final ]
|
||||
{
|
||||
// check for version change
|
||||
Set oId0 = $Get(^CacheTempUser("Singleton", ..%ClassName(1)))
|
||||
Set oRef0 = ..%Open(oId0) //,, .sc)
|
||||
If '$IsObject(oRef0) Quit $$$ERROR($$$GeneralError, "Failed to load singleton object.")
|
||||
If oRef0.Version = ..Version {
|
||||
Set ..Version = ..Version + 1
|
||||
} Else {
|
||||
Quit $$$ERROR($$$ConcurrencyVersionMismatch, ..%ClassName(1))
|
||||
}
|
||||
|
||||
// serialise local singleton object and check status code
|
||||
Set sc = ..%GetSwizzleObject(,.oId) If $$$ISERR(sc) Quit sc
|
||||
|
||||
// acquire exclusive lock on global singleton object
|
||||
Set lockTO = $ZUtil(115,4)
|
||||
Lock +^CacheTempUser("Singleton", ..%ClassName(1)):lockTO
|
||||
If '$Test Quit $$$ERROR($$$LockFailedToAcquireExclusive, ..%ClassName(1))
|
||||
|
||||
// update global singleton object and release lock
|
||||
Set ^CacheTempUser("Singleton", ..%ClassName(1)) = oId
|
||||
Lock -^CacheTempUser("Singleton", ..%ClassName(1))
|
||||
Quit $$$OK
|
||||
}
|
||||
|
||||
Method %OnNew() As %Status [ Final, Internal ]
|
||||
{
|
||||
// do not allow constructor method to be called
|
||||
Quit $$$ERROR($$$GeneralError, "Can't instantiate directly.")
|
||||
}
|
||||
|
||||
Method %OnConstructClone() As %Status [ Final, Internal ]
|
||||
{
|
||||
// do not allow singleton object to be cloned
|
||||
Quit $$$ERROR($$$GeneralError, "Can't clone instance.")
|
||||
}
|
||||
|
||||
Method %OnClose() As %Status [ Final, Internal ]
|
||||
{
|
||||
// reference count for singleton object is now zero, so
|
||||
// release lock on global singleton object, if applicable
|
||||
If ..Concurrency = 3 Lock -^CacheTempUser("Singleton", ..%ClassName(1))#"S"
|
||||
If ..Concurrency = 4 Lock -^CacheTempUser("Singleton", ..%ClassName(1))
|
||||
Quit $$$OK
|
||||
}
|
||||
|
||||
Property Concurrency As %Integer [ Final, Private, Transient ];
|
||||
|
||||
Property Version As %Integer [ Final, Private ];
|
||||
|
||||
}
|
||||
|
|
@ -4,6 +4,6 @@
|
|||
// any instance variables
|
||||
}
|
||||
|
||||
+ (SomeSingleton*)sharedInstance;
|
||||
+ (SomeSingleton *)sharedInstance;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
// SomeSingleton.m
|
||||
@implementation SomeSingleton
|
||||
|
||||
+ (SomeSingleton*) sharedInstance
|
||||
+ (SomeSingleton *) sharedInstance
|
||||
{
|
||||
static sharedInstance = nil;
|
||||
if(!sharedInstance) {
|
||||
static SomeSingleton *sharedInstance = nil;
|
||||
if (!sharedInstance) {
|
||||
sharedInstance = [[SomeSingleton alloc] init];
|
||||
}
|
||||
return sharedInstance;
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
return UINT_MAX;
|
||||
}
|
||||
|
||||
- (void)release
|
||||
- (oneway void)release
|
||||
{
|
||||
// prevent release
|
||||
}
|
||||
|
|
|
|||
10
Task/Singleton/Objective-C/singleton-3.m
Normal file
10
Task/Singleton/Objective-C/singleton-3.m
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
+ (SomeSingleton *) sharedInstance
|
||||
{
|
||||
static SomeSingleton *sharedInstance = nil;
|
||||
@synchronized(self) {
|
||||
if (!sharedInstance) {
|
||||
sharedInstance = [[SomeSingleton alloc] init];
|
||||
}
|
||||
}
|
||||
return sharedInstance;
|
||||
}
|
||||
9
Task/Singleton/Objective-C/singleton-4.m
Normal file
9
Task/Singleton/Objective-C/singleton-4.m
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
+ (SomeSingleton *) sharedInstance
|
||||
{
|
||||
static SomeSingleton *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[SomeSingleton alloc] init];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
6
Task/Singleton/Racket/singleton-1.rkt
Normal file
6
Task/Singleton/Racket/singleton-1.rkt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#lang racket
|
||||
(provide instance)
|
||||
(define singleton%
|
||||
(class object%
|
||||
(super-new)))
|
||||
(define instance (new singleton%))
|
||||
6
Task/Singleton/Racket/singleton-2.rkt
Normal file
6
Task/Singleton/Racket/singleton-2.rkt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#lang racket
|
||||
(provide instance)
|
||||
(define instance
|
||||
(new (class object%
|
||||
(define/public (foo) 123)
|
||||
(super-new))))
|
||||
Loading…
Add table
Add a link
Reference in a new issue