Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: FIFO #14

Open
gaowanlu opened this issue Jun 25, 2024 · 0 comments
Open

feat: FIFO #14

gaowanlu opened this issue Jun 25, 2024 · 0 comments

Comments

@gaowanlu
Copy link
Member

// avant-fifo
#include <iostream>
#include <stdexcept>
#include <sys/types.h>
#include <sys/stat.h>
#include <functional>
#include <unistd.h>
#include <fcntl.h>
#include <cstring>
#include <fstream>
#include <thread>
#include <chrono>

namespace avant
{
    namespace ipc
    {
        class fifo
        {
        public:
            enum iam
            {
                AUTH_A = 0,
                AUTH_B = 1,
                AUTH_NONE = 2
            };

            fifo(const std::string &a2b_path,
                 const std::string &b2a_path,
                 iam me,
                 std::function<void(fifo &)> destory_callback) : a2b_path(a2b_path),
                                                                 b2a_path(b2a_path),
                                                                 me(me),
                                                                 destory_callback(destory_callback)
            {
            }

            ~fifo()
            {
                if (destory_callback)
                {
                    destory_callback(*this);
                }
                if (fd_a2b > 0)
                {
                    close(fd_a2b);
                    unlink(a2b_path.c_str());
                }
                if (fd_b2a > 0)
                {
                    close(fd_b2a);
                    unlink(b2a_path.c_str());
                }
            }

            void init()
            {
                if (a2b_path.empty())
                {
                    throw std::runtime_error("a2b_path empty");
                }
                if (b2a_path.empty())
                {
                    throw std::runtime_error("b2a_path empty");
                }
                int ret = mkfifo(a2b_path.c_str(), 0777);
                if (ret == -1)
                {
                    if (errno != EEXIST)
                    {
                        throw std::runtime_error("mkfifo a2b_path ret -1 and errno != EEXIST");
                    }
                }
                ret = mkfifo(b2a_path.c_str(), 0777);
                if (ret == -1)
                {
                    if (errno != EEXIST)
                    {
                        throw std::runtime_error("mkfifo b2a_path ret -1 and errno != EEXIST");
                    }
                }

                if (me == AUTH_A)
                {
                    fd_a2b = open(a2b_path.c_str(), O_RDWR);
                    if (fd_a2b <= 0)
                    {
                        throw std::runtime_error("AUTH_A open a2b err");
                    }
                    fd_b2a = open(b2a_path.c_str(), O_RDWR);
                    if (fd_b2a <= 0)
                    {
                        throw std::runtime_error("AUTH_A open b2a err");
                    }
                }
                else if (me == AUTH_B)
                {
                    fd_a2b = open(a2b_path.c_str(), O_RDWR);
                    if (fd_a2b <= 0)
                    {
                        throw std::runtime_error("AUTH_B open a2b err");
                    }
                    fd_b2a = open(b2a_path.c_str(), O_RDWR);
                    if (fd_b2a <= 0)
                    {
                        throw std::runtime_error("AUTH_B open b2a err");
                    }
                }
                else
                {
                    throw std::runtime_error("unknow me, it is not AUTH_A or AUTH_B");
                }

                // set nonblock
                {
                    int flags = fcntl(fd_a2b, F_GETFL, 0);
                    if (0 != fcntl(fd_a2b, F_SETFL, flags | O_NONBLOCK))
                    {
                        throw std::runtime_error("set nonblock fd_a2b err");
                    }

                    flags = fcntl(fd_b2a, F_GETFL, 0);
                    if (0 != fcntl(fd_b2a, F_SETFL, flags | O_NONBLOCK))
                    {
                        throw std::runtime_error("set nonblock fd_b2a err");
                    }
                }

                init_succ = true;
            }

            int write(const char *buffer, int len)
            {
                return 0;
            }

            int recv(char *buffer, int len)
            {
                return 0;
            }

        public:
            std::string get_a2b_path()
            {
                return a2b_path;
            }
            std::string get_b2a_path()
            {
                return b2a_path;
            }

        private:
            std::string a2b_path;
            std::string b2a_path;
            int fd_a2b{-1};
            int fd_b2a{-1};
            iam me{AUTH_NONE};
            bool init_succ{false};
            std::function<void(fifo &)> destory_callback{nullptr};
        };
    }
}

int main()
{
    avant::ipc::fifo fifo_instance_a("/tmp/a2b_path",
                                     "/tmp/b2a_path",
                                     avant::ipc::fifo::AUTH_A,
                                     [](avant::ipc::fifo &_this) -> void
                                     {
                                         std::cout << "destory_callback a" << std::endl;
                                     });
    fifo_instance_a.init();

    avant::ipc::fifo fifo_instance_b("/tmp/a2b_path",
                                     "/tmp/b2a_path",
                                     avant::ipc::fifo::AUTH_B,
                                     [](avant::ipc::fifo &_this) -> void
                                     {
                                         std::cout << "destory_callback b" << std::endl;
                                     });
    fifo_instance_b.init();

    // constexpr int buffer_size = 512;
    // while (true)
    // {
    //     // A2B
    //     {
    //         static char a_send_buffer[buffer_size]{0};
    //         static char b_recv_buffer[buffer_size]{0};
    //     }
    //     // B2A
    //     {
    //         static char b_send_buffer[buffer_size]{0};
    //         static char a_recv_buffer[buffer_size]{0};
    //     }
    //     std::this_thread::sleep_for(std::chrono::milliseconds(50));
    // }

    return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant