Allow IOMethods to be explicit disposers

This commit changes IOMethods and clarifies stop functions that they
will act as destructors or disposers for whatever interface that
implements the methods, and that both the backend and frontend should
free that interface when they're called.

This commit is added as part of the IPC protocol.
This commit is contained in:
diamondburned 2021-01-13 16:17:55 -08:00
parent 06a26af5ba
commit 1460ee6b4b
5 changed files with 28 additions and 6 deletions

View File

@ -237,7 +237,7 @@ type Author interface {
// Backlogger adds message history capabilities into a message container. The
// backend should send old messages using the MessageCreate method of the
// MessageContainer, and the frontend should automatically sort messages based
// MessagesContainer, and the frontend should automatically sort messages based
// on the timestamp.
//
// As there is no stop callback, if the backend needs to fetch messages
@ -755,7 +755,7 @@ type Service interface {
//
// A session can implement SessionSaver, which would allow the frontend to save
// the session into its keyring at any time. Whether the keyring is completely
// secure or not is up to the frontend. For a Gtk client, that would be using
// secure or not is up to the frontend. For a GTK client, that would be using
// the GNOME Keyring daemon.
type Session interface {
// Identifier should typically return the user ID.
@ -776,7 +776,7 @@ type Session interface {
// When this function fails, the frontend may display the error upfront.
// However, it will treat the session as actually disconnected. If needed, the
// backend must implement reconnection by itself.
Disconnect() error // Blocking
Disconnect() error // Blocking, Disposer
// Asserters.

View File

@ -69,7 +69,11 @@ func generateInterfaces(ifaces []repository.Interface) jen.Code {
case repository.IOMethod:
stmt.Params(generateFuncParams(method.Parameters, "")...)
stmt.Params(generateFuncParamErr(method.ReturnValue, method.ErrorType)...)
stmt.Comment("// Blocking")
var comment = "Blocking"
if method.Disposer {
comment += ", Disposer"
}
stmt.Comment("// " + comment)
case repository.ContainerMethod:
stmt.Params(generateContainerFuncParams(method)...)
stmt.Params(generateContainerFuncReturns(method)...)

Binary file not shown.

View File

@ -69,6 +69,9 @@ func (m GetterMethod) ReturnError() bool {
// SetterMethod is a method that sets values. These methods must not do IO, and
// they have to be non-blocking. They're used only for containers. Actual setter
// methods implemented by the backend belongs to IOMethods.
//
// Clients should always keep track of the values given to setters and free them
// once the setters are called again with new values.
type SetterMethod struct {
method
@ -90,6 +93,17 @@ type IOMethod struct {
// returns. For the most part, this field should be "error" if that is the
// case, but some methods may choose to extend the error base type.
ErrorType string
// Disposer indicates that this method signals the disposal of the interface
// that implements it. This is used similarly to stop functions, except all
// disposer functions can be synchronous, and the frontend should handle
// indicating such. The frontend can also ignore the result and run the
// method in a dangling goroutine, but it must gracefully wait for it to be
// done on exit.
//
// Similarly to the stop function, the instance that the disposer method belongs
// to will also be considered invalid and should be freed once the function
// returns regardless of the error.
Disposer bool
}
// ReturnError returns true if the method can error out.
@ -110,6 +124,9 @@ type ContainerMethod struct {
// HasStopFn is true if the function returns a callback of type func() as
// its first return. The function will return an error in addition. If this
// is false, then only the error is returned.
//
// Once the stop function is called, the instance that the method belongs to
// will also be considered invalidated and should be freed accordingly.
HasStopFn bool
}

View File

@ -848,7 +848,7 @@ var Main = Packages{
A session can implement SessionSaver, which would allow the
frontend to save the session into its keyring at any time.
Whether the keyring is completely secure or not is up to the
frontend. For a Gtk client, that would be using the GNOME
frontend. For a GTK client, that would be using the GNOME
Keyring daemon.
`},
Name: "Session",
@ -888,6 +888,7 @@ var Main = Packages{
Name: "Disconnect",
},
ErrorType: "error",
Disposer: true,
},
AsserterMethod{ChildType: "Commander"},
AsserterMethod{ChildType: "SessionSaver"},
@ -1202,7 +1203,7 @@ var Main = Packages{
Comment: Comment{`
Backlogger adds message history capabilities into a message
container. The backend should send old messages using the
MessageCreate method of the MessageContainer, and the frontend
MessageCreate method of the MessagesContainer, and the frontend
should automatically sort messages based on the timestamp.
As there is no stop callback, if the backend needs to fetch