How to multithreading glfw CursorPos callback?

Hello guys i am trying to make a square and update it every time the cursor is moved.In fact everything works fine. i try to prevent a pause in rendering during some window interactions (e.g. resizing). When I move the cursor, rendering becomes slow (I mean the square is not catching up with the cursor). I’m sure I didn’t set up the thread correctly.Here is my code.

Rust / glfw / gl
extern crate gl;
extern crate glfw;

use self::gl::types::*;

use std::ffi::CString;
use std::mem;
use std::os::raw::c_void;
use std::ptr;
use std::str;

use glfw::Context;
use std::sync::mpsc::channel;
use std::sync::mpsc::{Receiver, Sender};
use std::thread::Builder;

#[derive(Debug)]
enum Act {
    MouseMove { x: f64, y: f64 },
    Close,
}

fn make_div(W: f32, H: f32, x: f32, y: f32, width: f32, height: f32) -> Vec<f32> {
    let left: f32 = ((x / (width / 2.0)) - 1.0);
    let top: f32 = -((y / (height / 2.0)) - 1.0);
    let bottom: f32 = -((y + H) / (height / 2.0) - 1.0);
    let right: f32 = ((x + W) / (width / 2.0) - 1.0);

    let mut shape: Vec<f32> = vec![];

    shape.append(&mut vec![left, bottom]);

    shape.append(&mut vec![right, bottom]);

    shape.append(&mut vec![right, top]);

    shape.append(&mut vec![left, top]);

    shape
}

const vertexShaderSource: &str = r#"
    #version 330 core
    layout (location = 0) in vec3 aPos;
    void main() {
       gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    }
"#;

const fragmentShaderSource: &str = r#"
    #version 330 core
    out vec4 FragColor;
    void main() {
       FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
    }
"#;

fn main() {
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
    glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3));
    glfw.window_hint(glfw::WindowHint::OpenGlProfile(
        glfw::OpenGlProfileHint::Core,
    ));
    #[cfg(target_os = "macos")]
    glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));

    let (mut window, events) = glfw
        .create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

    gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);

    window.set_cursor_pos_polling(true);

    let render_context = window.render_context();
    let (mut tx, rx): (Sender<Act>, Receiver<Act>) = channel();

    let render_task = Builder::new().name("render task".to_string());

    let render_task_done = render_task.spawn(move || {
        render(render_context, rx);
    });

    while !window.should_close() {
        // glfw.poll_events();
        glfw.wait_events();
        for (_, event) in glfw::flush_messages(&events) {
            handle_window_event(&mut window, event, &mut tx);
        }
    }

    tx.send(Act::Close)
        .ok()
        .expect("Failed signal to render thread.");

    let _ = render_task_done;
}

fn render(mut context: glfw::RenderContext, finish: Receiver<Act>) {
    context.make_current();

    let mut state_vao: u32 = 0;

    let (shaderProgram, VAO) = unsafe {
        let vertexShader = gl::CreateShader(gl::VERTEX_SHADER);
        let c_str_vert = CString::new(vertexShaderSource.as_bytes()).unwrap();
        gl::ShaderSource(vertexShader, 1, &c_str_vert.as_ptr(), ptr::null());
        gl::CompileShader(vertexShader);

        let mut success = gl::FALSE as GLint;
        let mut infoLog = Vec::with_capacity(512);
        infoLog.set_len(512 - 1); // subtract 1 to skip the trailing null character
        gl::GetShaderiv(vertexShader, gl::COMPILE_STATUS, &mut success);
        if success != gl::TRUE as GLint {
            gl::GetShaderInfoLog(
                vertexShader,
                512,
                ptr::null_mut(),
                infoLog.as_mut_ptr() as *mut GLchar,
            );
            println!(
                "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n{}",
                str::from_utf8(&infoLog).unwrap()
            );
        }

        let fragmentShader = gl::CreateShader(gl::FRAGMENT_SHADER);
        let c_str_frag = CString::new(fragmentShaderSource.as_bytes()).unwrap();
        gl::ShaderSource(fragmentShader, 1, &c_str_frag.as_ptr(), ptr::null());
        gl::CompileShader(fragmentShader);
        gl::GetShaderiv(fragmentShader, gl::COMPILE_STATUS, &mut success);
        if success != gl::TRUE as GLint {
            gl::GetShaderInfoLog(
                fragmentShader,
                512,
                ptr::null_mut(),
                infoLog.as_mut_ptr() as *mut GLchar,
            );
            println!(
                "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n{}",
                str::from_utf8(&infoLog).unwrap()
            );
        }

        let shaderProgram = gl::CreateProgram();

        gl::AttachShader(shaderProgram, vertexShader);
        gl::AttachShader(shaderProgram, fragmentShader);
        gl::LinkProgram(shaderProgram);
        gl::GetProgramiv(shaderProgram, gl::LINK_STATUS, &mut success);
        if success != gl::TRUE as GLint {
            gl::GetProgramInfoLog(
                shaderProgram,
                512,
                ptr::null_mut(),
                infoLog.as_mut_ptr() as *mut GLchar,
            );
            println!(
                "ERROR::SHADER::PROGRAM::COMPILATION_FAILED\n{}",
                str::from_utf8(&infoLog).unwrap()
            );
        }
        gl::DeleteShader(vertexShader);
        gl::DeleteShader(fragmentShader);

        let mut vertices: Vec<f32> = Vec::new();
        vertices.append(&mut make_div(100.0, 100.0, 10.0, 10.0, 300.0, 300.0));

        let indices = [
            // note that we start from 0!
            0, 1, 2, // first Triangle
            2, 3, 0, // second Triangle
        ];
        let (mut VBO, mut VAO, mut EBO) = (0, 0, 0);
        gl::GenVertexArrays(1, &mut VAO);
        gl::GenBuffers(1, &mut VBO);
        gl::GenBuffers(1, &mut EBO);
        gl::BindVertexArray(VAO);

        gl::BindBuffer(gl::ARRAY_BUFFER, VBO);
        gl::BufferData(
            gl::ARRAY_BUFFER,
            (vertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
            &vertices[0] as *const f32 as *const c_void,
            gl::STATIC_DRAW,
        );

        gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, EBO);
        gl::BufferData(
            gl::ELEMENT_ARRAY_BUFFER,
            (indices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
            &indices[0] as *const i32 as *const c_void,
            gl::STATIC_DRAW,
        );

        gl::VertexAttribPointer(
            0,
            2,
            gl::FLOAT,
            gl::FALSE,
            2 * mem::size_of::<GLfloat>() as GLsizei,
            ptr::null(),
        );
        gl::EnableVertexAttribArray(0);

        gl::BindBuffer(gl::ARRAY_BUFFER, 0);

        gl::BindVertexArray(0);

        (shaderProgram, VAO)
    };

    state_vao = VAO;

    // repeating ..
    fn update(x: f32, y: f32) -> u32 {
        unsafe {
            let mut vertices: Vec<f32> = Vec::new();
            vertices.append(&mut make_div(100.0, 100.0, x, y, 300.0, 300.0));

            let indices = [
                // note that we start from 0!
                0, 1, 2, // first Triangle
                2, 3, 0, // second Triangle
            ];

            let (mut VBO, mut VAO, mut EBO) = (0, 0, 0);
            gl::GenVertexArrays(1, &mut VAO);
            gl::GenBuffers(1, &mut VBO);
            gl::GenBuffers(1, &mut EBO);
            gl::BindVertexArray(VAO);

            gl::BindBuffer(gl::ARRAY_BUFFER, VBO);
            gl::BufferData(
                gl::ARRAY_BUFFER,
                (vertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
                &vertices[0] as *const f32 as *const c_void,
                gl::STATIC_DRAW,
            );

            gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, EBO);
            gl::BufferData(
                gl::ELEMENT_ARRAY_BUFFER,
                (indices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
                &indices[0] as *const i32 as *const c_void,
                gl::STATIC_DRAW,
            );

            gl::VertexAttribPointer(
                0,
                2,
                gl::FLOAT,
                gl::FALSE,
                2 * mem::size_of::<GLfloat>() as GLsizei,
                ptr::null(),
            );
            gl::EnableVertexAttribArray(0);

            gl::BindBuffer(gl::ARRAY_BUFFER, 0);

            gl::BindVertexArray(0);
            VAO
        }
    }

    loop {
        let open = finish.try_recv();

        if !open.is_err() {
            match open.unwrap() {
                Act::MouseMove { x, y } => {
                    state_vao = update(x as f32, y as f32);
                }
                Act::Close => {
                    break;
                }
            }
        }

        unsafe {
            gl::ClearColor(0.2, 0.3, 0.3, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT);
            gl::Scissor(0, 0, 300, 300);
            gl::Enable(gl::SCISSOR_TEST);

            gl::UseProgram(shaderProgram);
            gl::BindVertexArray(state_vao);
            gl::DrawElements(gl::TRIANGLE_FAN, 200, gl::UNSIGNED_INT, ptr::null());
        }
        context.swap_buffers();
    }

    glfw::make_context_current(None);
}

fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent, ch: &mut Sender<Act>) {
    match event {
        glfw::WindowEvent::CursorPos(xpos, ypos) => {
            ch.send(Act::MouseMove { x: xpos, y: ypos }).unwrap();
        }
        _ => {}
    }
}