Allgemeines
Anwendungsgebiet: | Distributed-Lock-Manager (DLM); siehe "Distributed-Lock-Manager (DLM)" |
Makrotyp: | S-Typ, MF-Format 3: C-/D-/L-/M-/E-Form; siehe "S-Typ-Makroaufrufe" |
Makrobeschreibung
Der Makro LKENQ generiert einen Lock. Existiert der Lock bereits, wird er nicht neu erstellt, aber die aufrufende Task wird ihm zugeordnet. Die Lock-Anforderung wird im angegebenen Lock-Modus in die Warteschlange eingereiht.
Ein Lock wird identifiziert mittels eines Lock-Namens und eines Geltungsbereiches. Der Lock-Name wird vom Benutzer an den DLM geliefert.
An die aufrufende Task wird eine Lock-Kurzkennung (LOCKID) zurückgeliefert, die in weiteren Aufrufen (LKCVT, LKCAN, LKDEQ) zur Bearbeitung angegeben werden muss. Die Lock-Kurzkennung ist eine task-spezifische Steuerung für den Lock.
Wurde der Lock bereits für diese Task in die Warteschlange eingereiht, wird die Lock-Kurzkennung der vorherigen LKENQ-Anforderung zurückgeliefert, aber der Makro wurde nicht ausgeführt. Der Lock-Modus wurde nicht verändert!
Makroaufrufformat und Operandenbeschreibung
LKENQ |
MF=C / D / L / M / E ,ASYNCTL=*SYNCH / *ASYNCH / <var: enum-of _asyncctl_s:1> ,GRANTID=0 / <var: int:4> ,GRTEVTT=*SYNCH / *TUCONTI / *TUEVENT / <var: enum-of _evttype_s:1> ,HOLDTIM=*INFINITE / *SYSTEM / <var: int:2> / <integer 0..32767> ,LCKMODE=*NU / *CR / *CW / *PR / *PW / *EX / <var: enum-of _lckmode_s:1> ,LSBADR=<var: pointer> ,LVBCTL=*IGNORE / *MOVE / <var: enum-of _lvbctl_s:1> ,MULTENQ=*NO / *YES / <var: enum-of _multiple_s:1> ,NAMEADR=<var: pointer> ,NAMELEN=0 / <integer 8..48> / <var: int:2> ,NAMRNGE=*OWNSYSTEM / *CLUSTER / <var: enum-of _namerange_s:1> ,SCOPE=*NAMESPACEID / *USERID / *GROUPID / <var: emun-of_scope_s:1> ,RELEVTT=*NO / *TUCONTI / *TUEVENT / <var: enum-of _evttype_s:1> ,RELID=0 / <var: int:4> ,TERMNTE=*STD / *FIRST / *SECOND / *THIRD / <var: enum-of _terminate_s:1> ,USERPAR=0 / <var: int:4> ,WAITTIM=*STD / *INFINITE / <var: int:2> / <integer 0..32767> ,WAITTYP=*TIME / *IMMEDIATE / <var: enum-of _timetype_s:1> ,PARAM=<var: pointer> / (reg: pointer>) ,PREFIX=N / p ,MACID=LDE / mac |
In der nachfolgenden Operandenbeschreibung sind die Operanden alphabetisch geordnet.
ASYNCTL=
Zuteilungssteuerung einer asynchronen Lock-Anforderung. Kann die Lock-Anforderung sofort zugeteilt werden, kann ein Contingency-Prozess oder ein Ereignis-Signal unterdrückt werden.
*SYNCH
Kann die Lock-Anforderung sofort zugeteilt werden, wird eine Zuteilungs-Contingency oder ein Ereignis-Signal unterdrückt.
*ASYNCH
Es wird immer eine Zuteilungs-Contingency oder ein Ereignis-Signal vom DLM erstellt, auch wenn die Lock-Anforderung sofort zugeteilt werden kann.
<var: enum-of _asyncctl_s:1>
Name des Feldes mit der Zuteilungs-Steuerung der asynchronen Lock-Anforderung zum Ausführungszeitpunkt.
GRANTID=
Kurzkennung für die Lock-Zuteilung. Gibt bei asynchronen Anforderungen an, welche Contingency-Kurzkennung oder Ereigniskennung die Information erhält, dass der Lock jetzt zugeteilt wurde.
<var: int:4>
Voreinstellung ist 0.
Die Contingency-Kurzkennung oder Ereigniskennung.
GRTEVTT=
Beschreibt in welcher Art Informationen über die Lock-Zuteilung zurückgeliefert werden sollen. Es gibt eine synchrone und zwei asynchrone Methoden zur Steuerung. Die angegebene Kurzkennung (Contingency-Kurzkennung oder Ereigniskennung) ist für die aktuelle Lock-Anforderung gültig. Andere Lock-Anforderungen von anderen Tasks können andere Kurskennungen angeben.
*SYNCH
Synchrone Lock-Anforderung. Rücksprung aus dem Makro, wenn der Lock zugeteilt oder eine Fehlerbedingung erkannt wurde. Die Information wird im Returncode zurückgeliefert.
*TUCONTI
Contingency-Prozess. Dieser Wert muss angegeben werden, um eine Bestätigung der Zuteilungs-Anforderung während der Contingency-Verarbeitung zu erhalten. Der Benutzer wird über inkompatible Lock-Anforderungen informiert, die von anderen Benutzern in die Warteschlange eingereiht wurden. Die Freigabe-Contingency wird gestartet, wenn der Lock sich in einem inkompatiblen Lock-Modus befindet.
*TUEVENT
Ereignissteuerung (Eventing). Um die Zuteilungs-Information zu erhalten, kann eine Ereignisvariable benutzt werden. Durch Aufruf des SOLSIG-Makros wird die Zuteilungs-Information geliefert. Die inkompatiblen Lock-Anforderungen von anderen Tasks werden über die selbe Ereignisvariable gemeldet.
<var:enum-of _evttype_s:1>
Name des Feldes mit dem Zuteilungs-Ereignis-Typ zum Ausführungszeitpunkt.
HOLDTIM=
Die Haltezeit ist die Zeit, die der Lock-Halter den Lock halten will. Nach Ablauf der Haltezeit wird ein Freigabe-Ereignis vom DLM erzeugt, damit der Lock-Halter seine Lock-Anforderung abschwächen bzw. freigeben kann.
Darf nur zusammen mit dem Operanden RELEVTT angegeben werden.
*INFINITE
Keine Haltzeitlimit.
*SYSTEM
Vom Betriebssystem definierte Haltezeit.
<var: int:2>
Vom Benutzer festgelegte Haltezeit in Sekunden.
<integer 0..32767>
Direkte Angabe der Haltezeit in Sekunden.
LCKMODE=
Gibt den Lock-Modus des angeforderten Locks an.
*NU
Der Lock befindet sich im Null-Modus und wird immer zugeteilt. Er ist mit allen anderen Lock-Anforderungen kompatibel. Ein Zugriff auf die Ressource ist nicht erlaubt.
*CR
Der Lock befindet sich im Concurrent-Read-Modus. Erlaubt sind andere Locks nur im Null-Modus, im Concurrent-Read-Modus, im Concurrent-Write-Modus, im Protected-Read-Modus und im Protected-Write-Modus. Dem Lock-Halter wird ein ungeschützter Lesezugriff auf die Ressource gewährt.
*CW
Der Lock befindet sich im Concurrent-Write-Modus. Erlaubt sind andere Locks nur im Null-Modus, im Concurrent-Write-Modus oder im Concurrent-Read-Modus. Dem Lock-Halter wird ein ungeschützter Schreibzugriff auf die Ressource gewährt.
*PR
Der Lock befindet sich im Protected-Read-Modus. Erlaubt sind andere Locks nur im Null-Modus, im Concurrent-Read-Modus oder im Protected-Read-Modus. Dem Lock-Halter wird ein geschützter Lesezugriff auf die Ressource gewährt.
*PW
Der Lock befindet sich im Protected-Write-Modus. Erlaubt sind andere Locks nur im Null-Modus und im Concurrent-Read-Modus. Dem Lock-Halter wird ein geschützter Schreibzugriff auf die Ressource gewährt.
*EX
Der Lock befindet sich im Exklusiv-Modus. Erlaubt sind andere Locks nur im Null-Modus. Nur der Lock-Halter darf auf die Ressource zugreifen.
<var: enum-of _lckmode_s:1>
Name des Feldes mit dem Lock-Modus.
LSBADR=
Feld mit der Adresse des Lock-Status-Blocks. Ein Teil des Lock-Status-Blocks ist der Lock-Value-Block.
<var: pointer>
Name des Feldes mit der Adresse des Lock-Status-Blocks.
LVBCTL=
Gibt die Behandlung des Lock-Value-Blocks an.
*IGNORE
Der Lock-Value-Block wird nicht benutzt.
*MOVE
Den Lock-Value-Block lesen oder schreiben. Der Lock-Value-Block kann gelesen werden, wenn der Lock zugeteilt wurde. Er kann geschrieben werden, wenn der Lock freigegeben wurde.
<var: enum-of _lvbctl_s:1>
Name des Feldes mit der Behandlung des Lock-Value-Blocks zum
Ausführungszeitpunkt.
MF=
Zur allgemeinen Beschreibung des Operanden MF, der dazugehörenden Operandenwerte und der evtl. nachfolgenden Operanden (z.B. PREFIX, MACID und PARAM) siehe Abschnitt „S-Typ-Makroaufrufe“. Die gültigen MF-Werte sind zu Beginn der Makrobeschreibung bei „Makrotyp“ angegeben und aus dem Aufrufformat ersichtlich.
Bei der C-Form, D-Form oder M-Form des Makroaufrufs kann ein Präfix PREFIX und bei der C-Form oder M-Form zusätzlich eine Macid MACID angegeben werden.
MULTENQ=
Mehrfache LKENQ-Anforderungen sind erlaubt.
Gibt an, ob der Benutzer mehr als eine Lock-Anforderung für denselben Lock-Namen (=Lock) in die Warteschlange einreihen darf. Jede dieser Lock-Anforderungen erhält ihre eigene Lock-Kurzkennung (LOCKID) und jede muss für sich wieder aus der Warteschlange freigegeben werden.
*NO
Existiert bereits eine Lock-Anforderung dieser Task für den angegebenen Lock, wird diese (aktuelle) Lock-Anforderung abgewiesen.
*YES
Diese (aktuelle) Lock-Anforderung wird unabhängig von bereits existierenden Lock-Anforderungen dieser Task für diesen Lock in die Warteschlange eingereiht. Diese Lock-Anforderung erhält ihre eigene eindeutige Lock-Kurzkennung (LOCKID).
<var: enum-of _multiple_s:1>
Name des Feldes mit dem Wert von MULTENQ zum Ausführungszeitpunkt.
NAMEADR=
Feld mit der Adresse des Lock-Namens.
<var: pointer>
Name des Feldes mit der Adresse des Lock-Namens.
NAMELEN=
Voreinstellung ist 0.
Gibt die Länge des Lock-Namens an.
<integer 8..48>
Direkte Angabe der Länge des Lock-Namens zum Übersetzungszeitpunkt.
<var: int:2>
Name des Feldes mit der Länge des Lock-Namens zum Ausführungszeitpunkt.
NAMRNGE=
Gibt an, in welchem Bereich der Lock-Name gültig ist. Wird eine LKENQ-Anforderung auf einem Single-System ausgeführt (das nicht Teil eines Clusters ist und auch nie Teil eines Clusters wird), wird der Lock behandelt, als sei das Single-System Teil eines Clusters. Diese Eigenschaft erlaubt das Portieren von Programmen von Single-Non-Clustered-Systemen auf Cluster-Systeme.
*OWNSYSTEM
Der angegebene Lock-Name ist nur auf dem lokalen System gültig.
*CLUSTER
Der angegebene Lock-Name ist clusterweit gültig.
<var: enum-of _namerange_s:1>
Name des Feldes mit dem Bereich, in dem der Lock-Name gültig ist, zum Ausführungszeitpunkt.
RELEVTT=
Beschreibt in welcher Art Informationen über die Lock-Freigabe zurückgeliefert werden sollen. Es gibt eine synchrone und zwei asynchrone Methoden zur Steuerung. Die angegebene Kurzkennung (Contingency-Kurzkennung oder Ereigniskennung) ist für die aktuelle Lock-Anforderung gültig. Andere Lock-Anforderungen von anderen Tasks können andere Kurzkennungen angeben.
*NO
Es werden keine Informationen über andere inkompatible Lock-Anforderungen, die diesen Lock betreffen ausgegeben. Dies kann zu Deadlock-Problemen führen, wenn der Lock nicht freigegeben wird. Ist die angegebene Haltezeit für diesen Lock abgelaufen, wird der Lock-Halter dieser Lock-Anforderung ohne weitere Meldung beendet.
*TUCONTI
Contingency-Prozess. Dieser Wert muss angegeben werden, um das Freigabe-Ereignis während der Contingency-Verarbeitung zu erhalten. Der Benutzer wird über inkompatible Lock-Anforderungen informiert, die von anderen Benutzern in die Warteschlange eingereiht wurden. Die Freigabe-Contingency wird gestartet, wenn der Lock sich in einem inkompatiblen Modus befindet.
*TUEVENT
Ereignissteuerung (Eventing). Um das Freigabe-Ereignis zu erhalten, kann eine Ereignisvariable benutzt werden. Durch Aufruf des Makros SOLSIG wird die Information geliefert. Die inkompatiblen Lock-Anforderungen von anderen Tasks werden über die selbe Ereignisvariable gemeldet.
<var:enum-of _evttype_s:1>
Name des Feldes mit dem Freigabe-Ereignis-Typ zum Ausführungszeitpunkt.
RELID=
Kurzkennung für die Lock-Freigabe. Gibt an, welche Contingency-Kurzkennung oder Ereigniskennung die Information erhält, dass die Lock-Anforderung eine andere Lock-Anforderung eines anderen Benutzers blockiert.
<var: int:4>
Voreinstellung ist 0.
Die Contingency-Kurzkennung oder Ereigniskennung.
SCOPE=
Bestimmt den lokalen Geltungsbereich des Lock-Namens.
*NAMESPACEID
ist Voreinstellung: Der angegebene Lock-Name wird als interner Lock-Name
verwendet. Der erste Teil (8 Byte) des angegebenen Lock-Namens bildet dabei implizit den lokalen Geltungsbereich. Der lokale Geltungsbereich muss eine Zeichenfolge sein. Die gültigen Zeichen sind die Buchstaben „A..Z”, „a..z”; die Ziffern „0..9” und die Sonderzeichen „@” und „#”. Die maximale Länge des angegebenen Lock-Namens ist 48 Zeichen.
*USERID
Die Benutzerkennung, zu der die Aufrufer-Task gehört, wird für die Bildung des internen Lock-Namens verwendet. Der DLM bestimmt die Benutzerkennung und setzt sie an den Anfang des Lock-Namens. Der erste Teil des angegebenen Lock-Namens wird nicht als lokaler Geltungsbereich betrachtet. Die maximale Länge des angegebenen Lock-Namens verringert sich auf 40 Zeichen.
Durch die Angabe des Operanden SCOPE=*USERID können die Locks einer Anwendung auf einfache Weise gegen den Zugriff einer anderen Anwendung geschützt werden. Die Anwendungen müssen nur unter verschiedenen Benutzerkennungen gestartet werden.
*GROUPID
Die Benutzergruppe, zu der die Aufrufer-Task gehört, wird für die Bildung des internen Lock-Namens verwendet. Der DLM bestimmt die Benutzergruppe und setzt sie an den Anfang des Lock-Namens. Der erste Teil des angegebenen Lock-Namens wird nicht als lokaler Geltungsbereich betrachtet. Die maximale Länge des angegebenen Lock-Namens verringert sich auf 40 Zeichen.
Der Operand SCOPE=*GROUPID darf nur angegeben werden, wenn das Software-Produkt SECOS im Einsatz ist, sonst führt der LKENQ-Aufruf zu einem Fehler.
<var: enum-of _scope_s:1>
Name des Feldes mit dem lokalen Geltungsbereich des Lock-Namens zum Ausführungszeitpunkt.
TERMNTE=
Gibt an, in welcher Reihenfolge dieser Lock während der abnormalen Beendigung des Lock-Halter-Prozesses (Task oder Programm) freigegeben wird. Die Beendigungs-
Sequenz ist in drei Klassen aufgeteilt. Die Locks des sich beendenden Prozesses werden freigegeben, unter Beachtung der angegebenen Sequenz oder sie werden alle zur gleichen Zeit freigegeben (von den anderen Prozessen aus gesehen).
*STD
Dieser Lock wird in der vom DLM festgelegten Beendigungs-Sequenz freigegeben.
*FIRST
Dieser Lock wird freigegeben, bevor oder zur gleichen Zeit, wie die Locks der folgenden Klasse freigegeben werden.
*SECOND
Dieser Lock wird freigegeben, nachdem oder zur gleichen Zeit, wie die Locks der vorherigen Klasse freigegeben werden. Und bevor oder zur gleichen Zeit, wie die Locks der folgenden Klasse freigegeben werden.
*THIRD
Dieser Lock wird freigegeben, nachdem oder zur gleichen Zeit, wie die Locks der vorherigen Klasse freigegeben werden.
<var: enum-of _terminate_s:1>
Name des Feldes mit der Beendigungs-Klasse zum Ausführungszeitpunkt.
USERPAR=
Enthält die Parameter für die asynchrone Mitteilungen. Sie werden an den Contingency-Prozess oder an die Ereignissteuerung übergeben.
<var: int:4>
Benutzerdefinierte Werte. Voreinstellung ist 0.
WAITTIM=
Die Wartezeit ist die Zeit, die gewartet werden soll, bis der Lock zugeteilt ist.
*STD
Standard-Wartezeit. Bei WAITTYP=*TIME entspricht dies *INFINITE. Bei Angabe von WAITTYP=*IMMEDIATE wird der Lock sofort zugeteilt oder der Auftrag beendet. Falls die Bearbeitung des Auftrages verzögert wird (Cluster, Netz), wird 600 Sekunden gewartet.
*INFINITE
Endlose Wartezeit. Die Anforderung überschreitet niemals das Zeitlimit. Die Lock-Anforderung wartet solange bis der Lock zugeteilt oder eine Deadlock-Situation erkannt wird.
<var: int:2>
Vom Benutzer festgelegte Wartezeit in Sekunden.
<integer 0..32767>
Direkte Angabe der Wartezeit in Sekunden.
WAITTYP
Gibt die Wartezeit-Art für wartende Lock-Anforderungen an.
*TIME
Der Wert der Zeitüberschreitung wird über den Operanden WAITTIM angegeben.
*IMMEDIATE
Sofort-Lock-Anforderung. Die Lock-Anforderung wird nicht in die Warteschlange eingereiht, wenn sie nicht sofort zugeteilt werden kann. Der Wert für die Zeitüberschreitung kann über den Operanden WAITTIM angegeben werden. Dieser Wert wird verwendet, wenn die Behandlung der Lock-Anforderung zu einem DLM-internen Warte-Zustand führt. Dies kann z.B. auftreten, wenn eine Netzwerk-Verbindung nicht mehr zur Verfügung steht, nachdem die Lock-Anforderung zur Verarbeitung an einen anderen Knoten gesendet wurde. Die notwendige Antwort wird dadurch von diesem anderen Knoten niemals übertragen. Um dies zu verhindern, kann der Benutzer eine Wartezeit über den Operanden WAITTIM angeben.
<var: enum-of _timetype_s:1>
Benutzer-definierte Werte.
Rückinformation und Fehleranzeigen
Standardheader:
+---------------+ | | | | | |c|c|b|b|a|a|a|a| +---------------+
Über die Ausführung des Makros LKENQ wird im Standardheader folgender Returncode übergeben (cc=Subcode2, bb=Subcode1, aaaa=Maincode):
X'cc' | X'bb' | X'aaaa' | Erläuterung |
X'00' | X'00' | X'0000' | Der Makro wurde normal ausgeführt. Der Lock wurde zugeteilt oder die |
X'00' | X'00' | X'0001' | Der Makro wurde normal ausgeführt. Die Lock-Anforderung wurde in die |
X'00' | X'00' | X'0002' | Der Makro wurde ausgeführt, aber der Lock-Status ist ungültig. Diese |
X'00' | X'01' | X'1001' | Die Länge des Lock-Namens ist zu groß. |
X'00' | X'01' | X'1002' | Die Adresse des Lock-Namens ist nicht verfügbar. |
X'00' | X'01' | X'1003' | Der Lock-Name ist nicht erlaubt. |
X'00' | X'01' | X'1004' | Der angegebene Namensraum ist ungültig. |
X'00' | X'01' | X'1005' | Der Lock-Status-Block ist nicht verfügbar. |
X'00' | X'01' | X'1006' | Der Typ des Operanden GRANTID ist nicht derselbe wie im Operanden |
X'00' | X'01' | X'1007' | Der Typ des Operanden RELID ist nicht derselbe wie im Operanden RE- |
X'00' | X'01' | X'1008' | Ungültige Kombination der Operanden GRTEVTT und RELEVTT. |
X'00' | X'01' | X'1009' | Ungültige Angabe im Operanden WAITTIM. |
X'00' | X'01' | X'100A' | Ungültige Angabe im Operanden HOLDTIM. |
X'00' | X'01' | X'100B' | Ungültige Angabe im Operanden LCKTYPE. |
X'00' | X'01' | X'1010' | Der Lock ist bereits für diese Task in die Warteschlange eingereiht. |
X'00' | X'01' | X'1015' | Ungültige Angabe im Operanden LCKMODE. |
X'00' | X'01' | X'10FF' | Ein falscher Parameter wurde angegeben, der keinen spezifischen |
X'00' | X'20' | X'2001' | Es trat ein interner Fehler auf. |
X'00' | X'20' | X'2003' | Es trat ein interner Fehler im Zusammenhang mit dem Ressourcen- |
X'00' | X'20' | X'2004' | Es trat ein interner Fehler im Zusammenhang mit der Zeitlimitüberschreitung |
X'00' | X'20' | X'2005' | Es trat ein interner Fehler im Zusammenhang mit der Lock-Anforderung |
X'00' | X'20' | X'2006' | Es trat ein interner Fehler im Zusammenhang mit XCS auf. |
X'00' | X'40' | X'4003' | Die vorherige Lock-Anforderung ist noch nicht beendet. |
X'00' | X'82' | X'8001' | Es können keine weiteren Locks angelegt werden. |
X'00' | X'82' | X'8002' | Das Zeitlimit wurde überschritten. |
X'00' | X'82' | X'8003' | Es ist im Moment nicht möglich, Locks mit NAMRNGE=*CLUSTER |
X'00' | X'82' | X'8005' | Die Lock-Anforderung wurde bereits gelöscht. |
X'00' | X'82' | X'8006' | Sofort-Lock-Anforderungen sind nicht möglich, weil bereits zugeteilte |
Weitere Returncodes, deren Bedeutung durch Konvention makroübergreifend festgelegt ist, können der Tabelle „Standard-Returncodes“ (Standardheader) entnommen werden.