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 // Backlogger adds message history capabilities into a message container. The
// backend should send old messages using the MessageCreate method of 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. // on the timestamp.
// //
// As there is no stop callback, if the backend needs to fetch messages // 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 // 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 // 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. // the GNOME Keyring daemon.
type Session interface { type Session interface {
// Identifier should typically return the user ID. // 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. // When this function fails, the frontend may display the error upfront.
// However, it will treat the session as actually disconnected. If needed, the // However, it will treat the session as actually disconnected. If needed, the
// backend must implement reconnection by itself. // backend must implement reconnection by itself.
Disconnect() error // Blocking Disconnect() error // Blocking, Disposer
// Asserters. // Asserters.

View File

@ -69,7 +69,11 @@ func generateInterfaces(ifaces []repository.Interface) jen.Code {
case repository.IOMethod: case repository.IOMethod:
stmt.Params(generateFuncParams(method.Parameters, "")...) stmt.Params(generateFuncParams(method.Parameters, "")...)
stmt.Params(generateFuncParamErr(method.ReturnValue, method.ErrorType)...) stmt.Params(generateFuncParamErr(method.ReturnValue, method.ErrorType)...)
stmt.Comment("// Blocking") var comment = "Blocking"
if method.Disposer {
comment += ", Disposer"
}
stmt.Comment("// " + comment)
case repository.ContainerMethod: case repository.ContainerMethod:
stmt.Params(generateContainerFuncParams(method)...) stmt.Params(generateContainerFuncParams(method)...)
stmt.Params(generateContainerFuncReturns(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 // 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 // they have to be non-blocking. They're used only for containers. Actual setter
// methods implemented by the backend belongs to IOMethods. // 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 { type SetterMethod struct {
method method
@ -90,6 +93,17 @@ type IOMethod struct {
// returns. For the most part, this field should be "error" if that is the // 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. // case, but some methods may choose to extend the error base type.
ErrorType string 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. // 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 // 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 // its first return. The function will return an error in addition. If this
// is false, then only the error is returned. // 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 HasStopFn bool
} }

View File

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