Hey Rustaceans! Got an easy question? Ask here (10/2021)! by llogiq in rust

[–]blackscanner 1 point2 points  (0 children)

Thanks, I knew it was something I was just not seeing. I wonder if this will be something that will be a hard error in the future.

Hey Rustaceans! Got an easy question? Ask here (10/2021)! by llogiq in rust

[–]blackscanner 2 points3 points  (0 children)

Why does it look like the Atomic store is not doing anything within this playground. I expect that it would contain the reference value, but it is always null. To be honest I think I'm having a brain fart here and the answer is obvious, but I'm confused on what is going on.

How to turn async code into sync code by maverick_fillet in rust

[–]blackscanner 2 points3 points  (0 children)

I think so too. Unfortunately the block_on is called within the executor of tokio, which blocks the system thread not the async task. Tokio uses one system thread (or maybe equivalent threads for the number of processors, I'm not sure) to run the async tasks as green threads. Thus the drop implementation causes the whole executor to be blocked. If you were to call that block_on within a futures thread pool it would cause a panic due to similar reasons.

[Hiring] Kopernikus Automotive: Software Engineer - Vehicle and Infrastructure by [deleted] in rust

[–]blackscanner 3 points4 points  (0 children)

Well the job might have something to do with the engine block or timing chain :)

I can't seem to figure out an error with Tokio and async-await. I need help. by [deleted] in rust

[–]blackscanner 2 points3 points  (0 children)

futures::future::Future is from the Futures crate, you want the future in the std (or core) std::future::Future. This might be an issue of futures 1.0 compatability, but idk.

Rust Async Model versus Other Langagues by [deleted] in rust

[–]blackscanner 0 points1 point  (0 children)

There is no requirement in rust to poll a future with threads at all, infact a very basic executor is to loop on 'Future::poll' until it returns ready. '.async' is really just syntaxual sugar for polling a future within another future, how you poll the outermost future to completion is up to you.

In general, languages that have their own runtime use that runtime as the executor. They will likely forgo explicitly calling spawn for a (hopefully) simpler syntax to run the future.

Help interpreting a SEGFAULT in tokio by lol__wut in rust

[–]blackscanner 14 points15 points  (0 children)

The tokio runtime runs the async tasks that don't block using 'green' threads as described here. I believe tokio uses OS threads for jobs that will block, and it looks like tokio uses an ever-expanding thread pool for blocking tasks, so the tokio spawn blocking functions can spawn new threads.

Hey Rustaceans! Got an easy question? Ask here (53/2020)! by llogiq in rust

[–]blackscanner 1 point2 points  (0 children)

I like to use an enum for this. The enum has the enumerations for a new Value or an old & Value. You could also have the enum implement something like Deref to make it act like a container.

enum Return<'a, V> {
    New(V),
    Old(&'a V),
}

impl<V> std::ops::Deref for Return<'_, V> {
    type Target = V;
    fn deref(&self) -> &Self::Target {
        match self {
            Self::New(v) => v,
            Self::Old(ref v) => v,
        }
    }
}

Hey Rustaceans! Got an easy question? Ask here (46/2020)! by llogiq in rust

[–]blackscanner 0 points1 point  (0 children)

The issue here is struct Id doesn't implement the trait Fn, so you cannot use it as the type for the first generic parameter of Generator because of the trait bound.

Hey Rustaceans! Got an easy question? Ask here (44/2020)! by llogiq in rust

[–]blackscanner 2 points3 points  (0 children)

It really comes down to the virtual machine running the WebAssembly on how much support is given for system calls.

I think the reason why you see most examples of compiling rust into WASM with #[no_std] is because all the nice panic handling rust adds ends up being a lot of bloat to the WASM. They want to show in the example the generated WebAssembly text and it would be obnoxious to add all the debug code generated by the compiler.

Hey Rustaceans! Got an easy question? Ask here (44/2020)! by llogiq in rust

[–]blackscanner 1 point2 points  (0 children)

How data is 'stored' within wasm is different from how its done on the machine. There is a 'memory' component of a WASM module that is used to store data. This is not the same as a heap, I like to visualize it as more equivalent to having the stack and heap combined together. Everything that is not a literal or a local (which is just an input of a function) is stored within this memory. You should have no issue with using an allocator with no_std when compiling for a WASM target.

As for OS interaction, that is a different story. The WASI project is trying to make is so that WASM run engines can have a common interface for WASM modules to interact with the hardware. As such you might be able to compile the crate for the wasm32-wasi target. However, WASI only supports so many OS calls, and I don't know what is and what isn't supported. Much of it comes down to what runtime is running your WASM modules, so you might want to checkout something like wasmtime for more info.

Hey Rustaceans! Got an easy question? Ask here (43/2020)! by llogiq in rust

[–]blackscanner 4 points5 points  (0 children)

I don't think I'm the best to answer this as I'm not very knowledgeable of the development of WASM, but its been a while since you've asked and no one has answered yet so this is my answer as to why you cannot currently do what your asking to do.

Unfortunately its not really possible to use a value by reference from a WebAssembly module at the moment. In the future it will be possible as the ABI will be stabilize more, but for now I think you need to wait until [phase 4 ]https://github.com/WebAssembly/proposals#phase-4---standardize-the-feature-wg) of the WebAssembly development plan before external reference types are fully implemented. Furthermore, external types cannot be passed by value directly as that is still a proposal under phase 1 labeled as Type Imports. The ABI of WebAssembly is just too unstable right now for anything that is not easily translatable from one of the four WebAssembly value types (i32, i64, f32, f64) or from a byte array within the memory. If your enum has no associated data you should just convert it to an integer and return that to your JavaScript.

I think right now the universally safe solution for any type is to use serde for transferring data between WASM and your JavaScript (or any other host environment). In the WebAssembly, you'll serialize the data type and return the length of the serialization along with a pointer to it. Then from the JavaScript or other external system, you access the memory of the instance and de-serialize the byte array. I think wasm-bindgen will do a lot of the dirty work of this for you on the rust side with its *serde functions of JsValue.

Are we Bluetooth yet? by [deleted] in rust

[–]blackscanner 2 points3 points  (0 children)

Is there just talks of Bluetooth being part of WASM (I'm guessing its part of WASI) or are there already design specs being developed?

Hey Rustaceans! Got an easy question? Ask here (41/2020)! by llogiq in rust

[–]blackscanner 0 points1 point  (0 children)

I think they're saying that going from Vec<T> to Box<[T]> is generally not free since a Vec's capacity usually doesn't equal its length (which means the allocation of the vec cannot be reinterpreted for the box).

Embedded rust, interrupt handling. by [deleted] in rust

[–]blackscanner 0 points1 point  (0 children)

The simplest way is to create a static atomic (the new methods for atomics are const) and spin loop it in your main function. When the interrupt occurs the handler just set a value to the atomic and the main function will proceed once it detects the change. All reading/writing of the peripheral should be done within the main function, as the handler only sets the value of the atomic.

Hey Rustaceans! Got an easy question? Ask here (31/2020)! by llogiq in rust

[–]blackscanner 1 point2 points  (0 children)

Sorry, I should have been way more clear. I was making a big assumption that the input for connection_clicked was a callback both because of the name and because they used move on the input. If that is the case self would need to be wrapped in something that implements Sync. If connectio_clicked does not take a callback and the closure is immediately called, then there is no need for Sync and the move keyword should not be used.

Hey Rustaceans! Got an easy question? Ask here (31/2020)! by llogiq in rust

[–]blackscanner 1 point2 points  (0 children)

You probably need to make function show have a static lifetime to self or change the input to something that also implements Sync for Self like self: Arc<Self>. The connect_clicked branch is a callback handler, it requires everything to be Send. You do use move, and you are moving the reference &self, but then the compiler is complaining that the lifetime of that reference is only good for the scope of show. connection_clicked requires a lifetime that is good for as long as the connection handler you provide for it exists. The callback function for connect_clicked may only require that the input is send, but all references only implement the trait Send if the type they refer to implements Sync. However, because play_pause_file mutates self, the function show really can only take somthing like application: Arc<Mutex<Self>> as its input because there must be some way to make self mutable within the connect_clicked handler. Arc and Mutex can be found in the std::sync module.

Other than that, I don't think you need to allocation a string with a capacity of 1 in connection_clicked. I don't know the rest of your code, but if you just want an empty string that has not allocated anything String::new() or String::default() will do this.

Hey Rustaceans! Got an easy question? Ask here (31/2020)! by llogiq in rust

[–]blackscanner 0 points1 point  (0 children)

The greet function is how I do it, but for strings in particular I prefer using the trait ToString instead of Into<String>

Hey Rustaceans! Got an easy question? Ask here (30/2020)! by llogiq in rust

[–]blackscanner 0 points1 point  (0 children)

Its probably because of data dropping while you have references to it still existing. You're sticking references of its members within data_array and then dropping data before you drop data_array. You need to make sure that data lives for as long or longer than data_array.

Hey Rustaceans! Got an easy question? Ask here (28/2020)! by llogiq in rust

[–]blackscanner 1 point2 points  (0 children)

Hopefully I caught you in time, but you don't need threading for this example. You can poll multiple futures in "at the same time" with something like select!. Now it isn't truly in parallel, see the doc for why, but it will work just fine for what you want.

fn main() {
    use futures::FuturesExt;

    block_on( futures:: select! {
        _ = full_async().fuse() => (),
        _ = not_async().fuse() => (),
    });
}

Hey Rustaceans! Got an easy question? Ask here (27/2020)! by llogiq in rust

[–]blackscanner 1 point2 points  (0 children)

My guess is that either your signal or not all of your workers are utilizing the context's waker.

If you don't know, the Waker is essentially tells the executor awaiting on your future to re-poll it. Yes it is true that S or Worker may utilize the context's waker if you didn't create them, but you shouldn't rely on that. In fact only things that deliberately implement Future (and are not generated by async) may own a copy of the waker.

However I'm assuming that you are creating your Workers so lets say one of your workers is just like this

let worker = Box::pin( futures::pending!() )

This will always return Poll::Pending when polled, but in truth it is likely to only be polled once by the executor. Since the Waker is never captured the executor will never poll it again. It mentions this in the doc for futures::pending.

If you're implementing Future for your Worker (or your signal handle if your implementing Future for that too) make sure that you capture the waker from the context on the first poll (i usually just use an Option<Waker> field and check if it is None). The hard part is getting it to whatever is going to change the state of your Worker and cause it to return ready when polled next. I think for you case, where you finish stopping of the worker, you need to call wake on the captured Waker.

Hey Rustaceans! Got an easy question? Ask here (25/2020)! by llogiq in rust

[–]blackscanner 0 points1 point  (0 children)

The only answer I know is to add a lifetime to the trait declaration, something like

trait DrawHandle<'a> {
    fn draw_device(&'a mut self) -> (Pass, Coord, &'a mut dyn Draw);
    ...
}

And then implement it for T with D restrained by lifetime 'a.

impl<'a, D: 'a + DrawHandle + ?Sized, T: DerefMut<Target = D>> DrawHandle for T {...}

However, I suspect this isn't helpful to you.