260 likes | 355 Views
Seminarium on Component-based Software Engineering. Callbacks and object re-entrance. Marcello Bonsangue LIACS – Leiden University Fall 2004. Libraries. A library is a collection of procedures It is always the client to call the library
E N D
Seminarium onComponent-based Software Engineering Callbacks and object re-entrance Marcello Bonsangue LIACS – Leiden University Fall 2004
Libraries • A library is a collection of procedures • It is always the client to call the library • Library operations run to completion before returning control Only states before and after a call are relevant to clients, library intermediate states are not observable Seminarium CBSE
Callbacks • A callback is a procedure that can be registered to a library so that the library can call it back • Example: registration of client code to be called when library catch user events • They are a mechanism for extensibility • Callbacks operate on the intermediate state of a library!! Seminarium CBSE
Callback: message sequence chart User Client Library Client installs callback User calls library Library invokes callback Callback queries library Callback returns Calls Results Library returns Seminarium CBSE
A Directory service example • The directory service supports callbacks to notify clients about changes in the managed directory • A client can use this mechanism to implement a visual display of the directory content. Seminarium CBSE
LIBRARY Directory Name=ARRAY OF CHAR; Notifier=PROCEDURE(IN name:Name); PROCEDURE ThisFile(n:Name): Files.File; (*pre n <>“” *) (*post result=file named n OR (result=NIL and no such file *) PROCEDURE addEntry(n:Name,f:Files.File); (* pre n<>“” and f<>NIL *) (* post ThisFile(n)=f *) PROCEDURE RemoveEntry(n:Name); (* pre n<>”” *) (* post ThisFile(n)=NIL *) PROCEDURE RegisterNotifier(n:Notifier); (* pre n<>NIL *) (* post n registered, will be called on AddEntry and RemoveEntry *) PROCEDURE UnregisterNotifier(n:Notifier); (* pre n<>NIL *) (* post n unregistered, will not be called anymore *); DirectoryDisplay (V 1.0) IMPORT Directory; PROCEDURE Notifer(IN n:DirectoryName); BEGIN IF Directory.ThisFile(n) = NIL THEN (*entry under name n has been removed – delete n in display *) ELSE (* entry has been added under name n – include n in display *) END Notifier; BEGIN Directory.RegisterNotifier(Notifier); END The Directory service details Seminarium CBSE
The Directory contract ambiguity • What happens on redefinition of an entry? • Notifier is not called … • Redefine uses thisfile (that does not call notifier) • …called once … • Redefine uses addEntry (that calls notifiers) • …twice • Redefine uses removeEntry and addEntry (and both call notifier) • The contract should specify who call notifier Seminarium CBSE
The Directory contract ambiguity • Is the notifier called before or after the directory is updated? • It is only sensible to call it after the update. • It should be in the contract Seminarium CBSE
LIBRARY Directory PROCEDURE addEntry(n:Name,f:Files.File); BEGIN Locate entry named n If not found append a new entry to the files list in this directory Else replace old binding with new file Call all registered notifiers END AddEntry; DirectoryDisplay (V 1.1) IMPORT Directory; PROCEDURE Notifier(IN n:Directory.Name); BEGIN IF Directory.ThisFile(n) = NIL THEN (* entry under name n has been removed – delete n in display *) ELSE IF n = “untitled” THEN Directory.RemoveEntry(n); ELSE (* entry has been added under name n include in display *) END END END Notifier; BEGIN Directory.Register(Notifier); END A new Directory display client Seminarium CBSE
Broken contract • Request of a user to create file “untitled” • Notifier() is called by the directory • File is removed by Notifier() • The AddEntry() post condition ThisFile(“Untitled”)=f is broken DirectoryDisplay User Directory RegisterNotifier(Notifier) AddEntry(“Untitled”,f) Notifier(“Untitled”) ThisFile(“Untitled”) RemoveEntry(“Untitled”) Notifier(“Untitled”) ThisFile(“Untitled”) Notifier returns RemoveEntry returns Notifier returns AddEntry returns Seminarium CBSE
What is the problem • The contract of the library does not says that notifiers do not have to change the file passed • Difficult to express as it is a transitive problem • Solutions: • Incorporates histories of interactions in specifications • Undecidable or very complex • Use state test functions in specifications • Test whether a particular operations is available Seminarium CBSE
Example: Java security manager use test function to protect critical services from being called by untrusted services. LIBRARY Directory PROCEDURE InNotifier():BOOLEAN; (* pre true *) (* post a notifier call is in progress *) PROCEDURE AddEntry(IN n:name:Name;f:Files.file(); (* pre (not InNotifier()and n<>”” and f<>NIL *) (* post ThisFile(n) = f *) PROCEDURE RemoveEntry(IN n:Name); (* pre not InNotifier() *) (* post ThisFile(n)=NIL *) Test functions Seminarium CBSE
Callbacks in objects • We can structure an application in layers. Object can references other objects on different layers: • Above the referenced object • Method invocation = regular call • Below the referenced object • Method invocation = up-call • Every method invoked as an up-call is a possible callback. Seminarium CBSE
A text processing example • A text model is a sequence of characters that supports random access to read,insert and delete characters • Text observers can register with the model and will be notified whenever a character is inserted or deleted • A text viewer extends an observer and provides visualization Seminarium CBSE
INTERFACE TextModel method write(int pos,char ch); //[len:int;txt:array of char; //pre len=this.length(); (all i:0<=i<len:txt[i]:=this.read(i)) and len< this.max() and 0<=pos<=len //post this.length() = len +1 and (all i:0<=i<=len:this.read(i):=txt[i]) and this.read(pos) = ch and (all i: pos<=i<=this.length(): this.read(i)=txt[i-1] method delete(int pos); // delete char at pos pos and shift all successive char back to one method max(): int; //pre true //post result=maximum length this text instance can have method length():int //pre true //post 0<=result<=this.max() and result=length of text method read(int pos):char; //pre 0<=pos<=this.length() //post result=character at position pos method register(TextObserver x); method unregister(TextObserver x); The TextModel Seminarium CBSE
INTERFACE TextObserver method insertNotification(int pos); //pre character at position pos has just been inserted method deleteNotification(int pos); //pre character that was at position pos has been deleted INTERFACE TextView EXTENDS TextObserver method text():TextModel //pre true //post result <> null method caretPos():int //pre true //post 0<=result<=this.text().length() method type(char ch) //pre caret:=this.caretPos():this.text().length() < this.text().max() //post this.caretPos()=caret+1 and post(this.text().write(caret,ch)) method setCaret(int pos); //pre 0<=pos<=this.text().length() //post this.caretPos()=pos method posFromCoord(int x,int y); //pre (x,y) is valid screen coordinate //post result=x,y-coordinates corresponding to text position pos method insertNotification(int pos); //post display updated and this.caretPos()=pos+1 method deleteNotification(int pos); //post display updated and this.caretPos()=pos The TextObserver and TextView Seminarium CBSE
Inserting a character Text Model Text View • Any callback? Client Display Write insertNotification (Remove caret mark) (Update text display) (Redisplay caret mark) Seminarium CBSE
Inserting a character (revised) • It reflects better the situation: TextView depends on the state of TextModel • See method Type Text View Text Model Client Display Write insertNotification (Remove caret mark) (Update text display) (Redisplay caret mark) Seminarium CBSE
Inter-object consistency • Control is transferred to other objects while still updating. In the example: • Display calls TextView’s map methods • But they can be called by other objects too! • Multiple observers could be registered • Which one gains control of display? • Consistency can be achieved by a disciplined programming • semaphores • synchronized methods • monitors Seminarium CBSE
Intra-object consistency • The real problem: Re-entrance • Re-entrance = an object method is invoked while another is still executing. • Methods have the right to change the state of their object, but what if it is called on an object that is not in a consistent state? Seminarium CBSE
Class Repository mystore :Store max = 100 method register(store) mystore:= store method add (elm) if store.check(max) then // code for adding elm to repository Object re-entrance Class Store var size:Int := 0 rep :Repository method insert(elm int); size:= size+1 rep.add(elm) method check (max) if size < max return true method notify(repository:Repository):Store rep:= repository rep.register(self) Display myStore User Notify(myrepository) Insert(elm) (add(elm) check(max) (Redisplay caret mark) Seminarium CBSE
Re-entrance (continued) • MyStore in in inconsistent state when the message check(max) is received • Obvious solution: • Switch the command lines size:= size+1 rep.add(elm) in the code of method insert(elm int) • It requires inspection of code, but components must be independently verifiable based on their contracts at interfaces Seminarium CBSE
Self-interference & re-entrance • Leads to inconsistent object state • Re-entrance is necessary • Recursive calls (direct or indirect) • As for callbacks it can be addressed by: • Introducing test functions for clients • Adding time-stamps to the state • Allowing histories of communication in specification • Not using method invocation Seminarium CBSE
Multithreading and re-entrance • Locking doesn’t solve the re-entrance problem • When strict re-entrance is solved, but leads to self-inflicted deadlocks • When relaxed(as in Java), suffers by re-entrance as in single threaded systems Seminarium CBSE
Histories • Alternative to specification contracts • Histories are sequences of messages • Restricting the permissible traces we can get valid state transitions • Permissible traces are hard to be checked dynamically Seminarium CBSE
Without method invocation • Explicit dependencies between state and events • Remember UML state machine obj!recall(book) obj?borrow(book) book on the shelf book on loan by obj obj?return(book) Seminarium CBSE