doc/wg/core/notes/core-notes-2021-10-15.md
N/A
allow into that framework, because everything's static, the
buffers you end up sharing with allow need to be static.allow and also the subscribe system calls so that the data that is
shared with allow and the drivers can be kept on the local stack frame rather than having to be static objects.allow would soundly work on the stack. It uses Pin. The unfortunate thing
about it is it means the drivers cannot call allow itself, instead the code using the drivers,
application level code, would have to make the allow call and that's kind of shifting the responsibility
for allow to code that it doesn't belong in, but that's in order to make sure that the unallow
happens in time. If we attempt to do this with subscribe then you have the additional challenge of dealing
with callbacks and injecting a function as a generic, which is really difficult.subscribe. I am considering making all drivers
that requires subscribe static objects, as subscribe works with static references, but have the allow system calls
work with stack local types. That combination might be doable and that is the avenue that I am currently exploring.allow that has a non-static lifetime, you have to make sure that
the memory is unallowed before it gets used for something else. For allow_readonly it's a threat model consideration,
while for allow_readwrite it's a soundness consideration.subscribe is a reference with a non-static lifetime, you have to make sure that
the unsubscribe happens before the lifetime ends.allows at the start of a block and then revokes at the end of the block,
and inside you have a blocking call?allow at
the beginning of the block and I'm gonna revoke the end of the block and then as long as I can show that the thing's I'm
allowing lifetime is longer than lifetime of that block, which isn't a problem on the stack, then you're okay. It's kind
of like the C++ construction for mutexes where a block can run for a mutex, so you hold the mutex for that block.mem::forget. You can call that anytime. When you call mem::forget in safe code it can't cause undefined behavior. It can cause bad stuff, like you poison your mutexs, but it's still not undefined
behaviour. The tricky part here is with sharing memory to the kernel. If you call mem::forget on the shared object
you won't unsubscribe or unallow, and so now you're breaking the aliasing rules, as the kernel does have access to
the same memory that the rust application does. This is undefined behaviour.drop, because you can call safe
function that prevent drop from happening.mem::forget, and that's one of the gotchas with that the Drop. You can cause incorrect behavior with mem::forget, stuff you would not want, but it has to still be defined and not break aliasing rules.mem::forget does not run the destructor.Drop impl to get called to unsubscribe or to unallow then all of
a sudden, you're in undefined behavior teritory. I recently did this last week or two weeks ago when we did a
stack based thing. I can send examples out. We didn't rely on drop.mem::forget, I have to have a reference to mem::forget?unallow or unsubscribe. This is how I understood your example of using a
mutex.allowed at the beginning of this block
and I rovoke at the end of the block.Drop trait it is overcomeable.mem::forget. If I allow, I should not have a reference anymore.
I would get the reference back by doing another allow and revoking the previous one.allowed buffer. For instance, its lifetime or
whether is an immutable or mutable buffer.allow would be calling a macro?subscribes that run in parallel.allows and subscribes it needs, and then you combine those operations
via another type level list into an awful generic argument into a function. The function materializes all of
the on-stack structures that you need to do those allow and subscribe calls and guarantees that unallow
and unsubsribe are called correctly and invokes the callback.static_init! as a macro is that the macro only gets expended once at compile time,
so if you put the macro into a function and than call the function multiple times, the body is the same, regardless
of the arguments of the function as the arguments are runtime options. The idea here is that because these are
going to be generic functions, you will end up with a lot of monomorphized functions and, as a result, the expanded
macro will be different in each of these functions. That is how we are hiding the macro from the user,
despite the fact that we need different expanded code for each call.allow, subscribe, command, upcall,
handlaing this should be much easier than when you have a series of upcalls, like an alarm. If you introduce
some blocking operation, than you can tie the lifetime of what's going on to that operation.subscribe,
but then looking through the OpenSK code base killed that idea.docs folder.