[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
1.1 Zusammenarbeit mit anderen Programmen | ||
1.2 Systemlisten und Schutzprotokolle |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
‘RSYS’ wurde unter Berücksichtigung aller mir bekannten Richtlinien der Programmierung unter AmigaOS 2.0 geschrieben. Alle kritischen Routinen wurden bis zu dreimal abgesichert. Das bläht zwar etwas den Code, gewährleistet aber die Lauffähigkeit auch unter Betriebssystemen >= 2.04.
Besonderer Wert wurde auf die Vermeidung von Speicherfehlern und ‘Enforcer’-Hits gelegt. Bei einem auftretenden Speicherfehler wird in den meisten Fällen das Programm unter Angabe von Quelldatei- und Funktionsname, sowie der Zeilennummer im Quelltext abgebrochen und beendet.
‘RSYS’ ist darauf ausgelegt, mit allen Programmen so gut wie möglich zusammenzuarbeiten. Das schließt jedoch die Programme aus, die von Haus aus Hacks sind, die sich nicht an die Programmierrichtlinien unter AmigaOS halten. Weiterhin hat ‘RSYS’ keinerlei Problem mit systemkonformen Patches, wie z.B. ‘MagicMenu’ von Martin Korndörfer, oder ‘MFR’ von Stefan Stuntz.
Viele Leute haben mich per EMAIL angeschrieben, daß ich doch bitte
OS 3.0-Features verwenden soll. ‘RSYS’ soll eigentlich unter
allen Systemen >2.0 laufen, weswegen ich spezielle Features von 3.0
absichtlich vermieden habe. Ausnahmen bilden jedoch einige verwendete
Tags, wie z.B. die GTM_NewLookMenus
, das die
Standard-3.0-Menüfarben einstellt. Diese werden von OS 2.x-System
ignoriert, womit also dem Einbau nichts im Wege stand.
Ein weiteres Feature von OS 3.0 ist die Routine
GT_GetGadgetAttrsA
der ‘gadtools.library’. Damit wird eine
vollständige Steuerung der ListView-Gadgets über Pfeiltasten ermöglicht.
Diese ist jedoch unter 2.x noch nicht implementiert, sodaß auch dieses
Feature in ‘RSYS’ aus Gründen der Kompatibilität nichts zu
suchen hat.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Intuition-Objekte werden beim Auslesen der Daten mit dem Protokoll LockIBase() / UnlockIBase() geschützt. Damit werden die jeweiligen Listen vor der Veränderung durch Intuition-Routinen während des Auslesens ausreichend geschützt. Bei der Veränderung der Objekte durch ‘RSYS’ ist selten ein Schutzprotokoll erforderlich, da die Routinen von Intuition dieses meistens selbst erledigen.
Alle Exec-Objekte, wie Tasks, Ports, Libraries, etc., werden während des Auslesens durch ein Forbid()/Permit(), im Falle von Tasks, sogar durch ein Disable()/Enable() vor Veränderung durch Systemroutinen geschützt. Im Falle der Tasks ist zum Auslesen der Taskzeiger das Protokoll Disable()/Enable() zu verwenden, zum Auslesen der Taskstruktur reicht jedoch ein Forbid()/Permit().
Disable()/Enable() sollte deswegen verwendet werden, da die Systemliste in der ExecBase durch den interruptgesteuerten Task-Scheduler laufend in ihrer Anordnung geändert wird (man denke nur an die Aktivierung eines Tasks, also die Umsetzung des entsprechenden Taskknotenzeigers aus der Wait-Liste in die Ready-Liste und dann in den Running-Zustand [ExecBase->ThisTask-Eintrag]).
Die Task-Struktur selber kann jedoch nur von einem Task oder Prozeß aus verändert werden. Daher reicht zum Auslesen der Taskstruktur das Protokoll Forbid()/Permit() aus. Daraus ergibt sich also folgendes Schema:
Reservieren der eigenen Struktur-Speicherbereiche Forbid(); Disable(); Auslesen und Merken der Tasknodes Enable(); Auslesen der Taskstrukturen in eigene Strukturen (ohne Verwendung von DOS-Routinen, also KEIN FGets(), Open() etc.) Permit(); Auswerten der eigenen Strukturen Freigeben der eigenen Struktur-Speicherbereiche
Für die Implementation dieser Routinen könnt Ihr den dokumentierten Quelltext einsehen.
Unter diesen Vorsichtsmaßnahmen sollte es keine Probleme im
Zusammenspiel mit anderen Programmen geben, bis auf eine Einschränkung:
‘RSYS’ kann nicht mit Programmen zusammenarbeiten, die
nicht systemkonform programmiert wurden. Beispiele dafür sind Programme,
die beispielsweise den Namen eines öffentlichen Ports nicht korrekt
initialisieren. So kommt es beispielsweise vor, daß ein Programm zwar
einen Zeiger auf einen Portnamen ungleich Null hat, diesen Zeiger aber
uninitialisiert läßt und dieser dann folglich irgendwohin zeigt. Die
Folge ist im harmlosesten Fall ein ‘Enforcer’-Hit des Typs
READ-BYTE
(beim Auslesen des vermeintlichen Strings), im extremsten
Fall ein Guru!
Ich habe das Problem jetzt so gelöst, daß ich bei den auszulesenen
Node-Namen das Typen-Flag untersuche. Steht dort der Eintrag NT_UNKNOWN
oder nicht das erwartete Flag, lese ich den String einfach nicht aus,
sondern trage in das ListView
<wrong type:0>
ein. Hierbei steht die 0
für den ermittelten Knotentypen. Die
möglichen Knotentypen sind:
Wert Typ ------------------------------------------------------ 0 Unbekannter Node-Typ 1 Task 2 Interrupt 3 Device 4 Message Port 5 Message 6freie
Message 7 Message wurde beantwortet 8 Resource 9 Library 10 Memory-Node 11 Softinterrupt 12 Font 13 Prozeß 14 Semaphor 15 Signalsemaphor 16 Boo-Node 17 Kick-Memory-Node 18 Graphics-Node (Monitor-Node z.B.) 19 Death Message (einetote
Nachricht) 254 Benutzerdefinierter Node 255 Erweiterung (auch benutzerdefiniert)
Manche Systemutilities (z.B. ARTM) achten darauf nicht und produzieren ‘Enforcer’-Hits en mas. Diese Fehler lassen sich auch nicht vermeiden. Der Aufwand dafür wäre einfach zu groß, da man ja praktisch Teile des Programms ‘Enforcer’ in das eigene Programm implementieren müßte. Solange man nicht davon ausgehen kann, daß JEDER Programmierer systemkonform programmiert, wird es diese Lücke auch weiterhin geben.
Ein weiterer typischer Fehler ist die Verwendung der Compiler-Funktion
strcpy() auf Quellstrings vorher unbekannter Länge. Viele
Programmierer verwenden diese Routine, um schneller Strings zu kopieren.
Dabei wird nicht beachtet, daß man eventuell gar nicht soviel Speicherplatz
reserviert hat, um den Quellstring aufzunehmen. Ein signifikantes
Beispiel dafür ist das o.g. Port-Namen-Problem. Ist der String
uninitialisiert und nicht mit ASCII 0
terminiert, kopiert
strcpy() einen solchen Portnamen bis in alle Ewigkeit, bis zum Ende
des Speichers, bis zur nächsten Einsprungadresse eines anderen Tasks oder
bis zur nächsten Reise von Indian tours :-)
Manche Programmierer sagen sich dann, überprüfen wir doch einfach mit
strlen() den Quellstring. Nun, da strlen() auch solange zählt, bis ASCII
0
erkannt wurde, ist diese Methode auch für eine Auslandsreise nach Indien
durchaus geeignet.
Das einfachste und probateste Mittel in diesem Fall, ist die
Compiler-Funktion strncpy(). Damit kann man einfach festlegen,
wieviel Zeichen denn nun kopiert werden sollen. Das einzige, was jetzt
noch stört, ist der READ-BYTE
-Hit den man bekommt, wenn man
merkwürdige Adressen an strncpy() übergibt.
Ein weitere Fehlerquelle ist die Verwendung von printf() in allen seinen Erscheinungsformen (sprintf(), vsprintf() etc.) im Zusammenhang mit Systemlisten. Da die printf()-Routinen auch auf DOS-Routinen zugreifen, sind sie zum zügigen Kopieren von mehreren Systemeinträgen ungeeignet. Die Routine RawDoFmt() der Exec-Library ist jedoch sicher. Mit ihr kann man sich selbst ein sprintf() zusammenbauen, was ich auch getan habe. Normalerweise befindet sich aber diese Routine in der ‘amiga.lib’.
Sicher ist weiterhin die Verwendung der str...()-Routinen zwischen Schutzprotokollen, da diese nur Speicherbereiche kopieren oder verschieben. Möchte man es trotzdem noch schneller haben, gibt es noch die Funktionen CopyMem() und CopyMemQuick(). Bei letzterer ist zu beachten, daß die Daten auf longwords ausgerichtet sein müssen. Beide Routinen gehören zur ‘exec.library’, können also bei Systemlistenuntersuchungen verwendet werden.
[Top] | [Contents] | [Index] | [ ? ] |
This document was generated on February 6, 2023 using texi2html 5.0.
The buttons in the navigation panels have the following meaning:
Button | Name | Go to | From 1.2.3 go to |
---|---|---|---|
[ << ] | FastBack | Beginning of this chapter or previous chapter | 1 |
[ < ] | Back | Previous section in reading order | 1.2.2 |
[ Up ] | Up | Up section | 1.2 |
[ > ] | Forward | Next section in reading order | 1.2.4 |
[ >> ] | FastForward | Next chapter | 2 |
[Top] | Top | Cover (top) of document | |
[Contents] | Contents | Table of contents | |
[Index] | Index | Index | |
[ ? ] | About | About (help) |
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated on February 6, 2023 using texi2html 5.0.