惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
L
LangChain Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Blog — PlanetScale
Blog — PlanetScale
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
T
Tailwind CSS Blog
T
The Blog of Author Tim Ferriss
U
Unit 42
B
Blog
N
Netflix TechBlog - Medium
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
O
OpenAI News
M
MIT News - Artificial intelligence
D
DataBreaches.Net
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
LINUX DO - 热门话题
C
CERT Recently Published Vulnerability Notes
V
Visual Studio Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
News and Events Feed by Topic
Vercel News
Vercel News
T
Tenable Blog
Security Latest
Security Latest
C
Check Point Blog
云风的 BLOG
云风的 BLOG
PCI Perspectives
PCI Perspectives
月光博客
月光博客
TaoSecurity Blog
TaoSecurity Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Project Zero
Project Zero
雷峰网
雷峰网
IT之家
IT之家
H
Hacker News: Front Page
Microsoft Security Blog
Microsoft Security Blog
B
Blog RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Last Week in AI
Last Week in AI
G
Google Developers Blog
Forbes - Security
Forbes - Security
The Register - Security
The Register - Security
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Martin Fowler
Martin Fowler
K
Kaspersky official blog
P
Proofpoint News Feed
T
Threatpost
Google Online Security Blog
Google Online Security Blog
Microsoft Azure Blog
Microsoft Azure Blog

Dosk 技术站

华为荣耀电视盒子刷 Armbian - Dosk 技术站 记录一个没意义的 usb wifi 驱动编译 - Dosk 技术站 我的 2024 - Dosk 技术站 unRAID 7.0.0-beta.1 - Dosk 技术站 关于 unraider 的开心版 - Dosk 技术站 unRAID 6.12.7-rc2 进展 - Dosk 技术站 每年问自己 40 个问题 - Dosk 技术站 Kubernetes 集群导航页 - Dosk 技术站 2023 年度总结 - Dosk 技术站 N100 万兆软路由最终形态 - Dosk 技术站 N100 软路由改造下散热 - Dosk 技术站 N100 万兆软路由测测速 - Dosk 技术站 整活新玩具,半 DIY 一个万兆软路由 - Dosk 技术站 玩玩 WebAuthn:RP2040 One - Dosk 技术站 关于最近以及后续要做什么 - Dosk 技术站 unRAID 6.12.0-rc7/6.12.0-rc6.13 - Dosk 技术站 unRAID 6.12.0-beta18 试用 - Dosk 技术站 unRAID 6.11.4 如何继续开心 - Dosk 技术站 cert-manager 基于 acme.sh 的 webhook - Dosk 技术站 unRAID 虚拟机运行 unRAID 简单步骤 - Dosk 技术站 解决 Chrome 原生谷歌翻译功能的一个思路:3/3 - Dosk 技术站 解决 Chrome 原生谷歌翻译功能的一个思路:1/3 - Dosk 技术站 unraid 命令行包管理器 - Dosk 技术站 继续,unraid 6.11 happy 的方法 - Dosk 技术站 适用于 k8s 的 frpc ingress 实现 - Dosk 技术站 实现了一个简单的通配 DNS 服务 - Dosk 技术站 代码更新,happy unraid 懒人版 - Dosk 技术站 复盘一次群晖的 btrfs + docker:dind 引发的灾难 - Dosk 技术站 unraid 官方版不修改不用 keymaker 可持续 happy 的方法 - Dosk 技术站 unraid 实现完美硬盘启动 - Dosk 技术站 rpi3b+ 跑 pi-kvm 项目记录 - Dosk 技术站 记录一下 docker 里跑 dsm 迅雷套件的过程 - Dosk 技术站 docker 更新,整理 build - Dosk 技术站 记录下 openwrt 改交换机的步骤,以及注意事项 - Dosk 技术站 docker 里跑 openwrt 遇到的奇奇怪怪问题修复 - Dosk 技术站 OpenWrt 添加一个 socat 的 luci web 界面 - Dosk 技术站 Cloudflare DDNS 脚本,适配 OpenWrt,自带的不好用 - Dosk 技术站 在 NAS 里优雅的使用迅雷 - Dosk 技术站 记录一次 rpi4b 使用 openwrt docker 接管网络 - Dosk 技术站 悲伤是一件很耗费精力的事情 - Dosk 技术站 Tablet 板绘 - 梅花 - Dosk 技术站 Tablet 板绘 - 月光 - Dosk 技术站 测试测试 Forestry - 一个 Jekyll CMS - Dosk 技术站 如何从 Chromium “偷” UI - Dosk 技术站 Cocoa 如何创建置于全屏之上的 NSWindow - Dosk 技术站 修改 Prose 支持中文标题 - Dosk 技术站 macOS & Windows 实现系统/进程/线程的 CPU 统计 - Dosk 技术站 STL 内 std::{bind/tuple/function} 简单实现 - Dosk 技术站 Cocoa 修改 TitleBar 样式 - Dosk 技术站
Chromium 代码下并发 Callback 的骚操作 - Dosk 技术站
2021-09-10 · via Dosk 技术站

我狗哥想同时发起多个异步操作,并在都结束时去处理结果;我说你写个状态机就行了呗,他觉的麻烦(嗯,麻烦是他的口头禅了),

代码库是 chromium,所以我决定想办法在 base::OnceCallback 上做做文章

/*
 *  Author: SpringHack - springhack@live.cn
 *  Last modified: 2021-09-11 00:08:59
 *  Filename: neotix_callback_helper.h
 *  Description: Created by SpringHack using vim automatically.
 */
#ifndef _NEOTIX_CALLBACK_HELPER_H_
#define _NEOTIX_CALLBACK_HELPER_H_

#include "base/atomic_ref_count.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/memory/weak_ptr.h"

namespace neotix {
namespace callback {

template <typename... CallbackTypes>
class UnionCallback {
 public:
  using FinallyCallback = base::OnceCallback<void(
      std::unique_ptr<UnionCallback<CallbackTypes...>>)>;

  class CallbackResultBase {};

  template <typename... InvokeTypes>
  class CallbackResult : public CallbackResultBase {
   public:
    std::tuple<InvokeTypes...> result;
  };

  class UnionCallbackWrapper {
   public:
    explicit UnionCallbackWrapper(UnionCallback<CallbackTypes...>* ptr)
        : ptr_(ptr) {}
    ~UnionCallbackWrapper() = default;
    UnionCallback<CallbackTypes...>* operator->() { return ptr_; }
    void Reset() {
      if (ptr_) {
        delete ptr_;
      }
      ptr_ = nullptr;
    }

   private:
    UnionCallback<CallbackTypes...>* ptr_;
  };

  static UnionCallbackWrapper Create() {
    UnionCallbackWrapper wrapper(new UnionCallback<CallbackTypes...>());
    return wrapper;
  }

  explicit UnionCallback() {
    counter_.Increment(callback_count);
    results_.resize(callback_count);
  }

  ~UnionCallback() = default;

  template <size_t index,
            typename CallbackType = typename std::
                tuple_element<index, std::tuple<CallbackTypes...>>::type>
  CallbackType GetCallback() {
    CallbackType cb = base::DoNothing();
    return GetCallbackInternal<index>(std::move(cb));
  }

  template <size_t index,
            typename CallbackType = typename std::
                tuple_element<index, std::tuple<CallbackTypes...>>::type>
  auto GetResult() {
    CallbackType cb = base::DoNothing();
    return GetResultInternal<index>(std::move(cb));
  }

  void Finally(FinallyCallback finally_cb) {
    finally_cb_ = std::move(finally_cb);
  }

 private:
  template <size_t index, typename... InvokeTypes>
  base::OnceCallback<void(InvokeTypes...)> GetCallbackInternal(
      base::OnceCallback<void(InvokeTypes...)>) {
    return base::BindOnce(
        &UnionCallback<CallbackTypes...>::DoCallbackInternal<index,
                                                             InvokeTypes...>,
        weak_factory_.GetWeakPtr());
  }

  template <size_t index,
            typename... InvokeTypes,
            typename ResultType = std::tuple<InvokeTypes...>>
  ResultType GetResultInternal(base::OnceCallback<void(InvokeTypes...)>) {
    CallbackResult<InvokeTypes...>* result =
        static_cast<CallbackResult<InvokeTypes...>*>(results_[index].get());
    if (!result) {
      CallbackResult<InvokeTypes...> default_result;
      return default_result.result;
    }
    return result->result;
  }

  template <size_t index, typename... InvokeTypes>
  void DoCallbackInternal(InvokeTypes... args) {
    if (!results_[index]) {
      CallbackResult<InvokeTypes...>* result =
          new CallbackResult<InvokeTypes...>();
      result->result = std::make_tuple(args...);
      results_[index].reset(result);
    }
    counter_.Decrement();
    if (counter_.IsZero()) {
      std::unique_ptr<UnionCallback<CallbackTypes...>> self(this);
      std::move(finally_cb_).Run(std::move(self));
    }
  }

  base::AtomicRefCount counter_;
  FinallyCallback finally_cb_ = base::DoNothing();
  const size_t callback_count = sizeof...(CallbackTypes);
  std::vector<std::shared_ptr<CallbackResultBase>> results_;
  base::WeakPtrFactory<UnionCallback<CallbackTypes...>> weak_factory_{this};
};

}  // namespace callback
}  // namespace neotix

#endif  // _NEOTIX_CALLBACK_HELPER_H_
using UnionCallbackDemo = neotix::callback::UnionCallback<
    base::OnceCallback<void(int)>,
    base::OnceCallback<void(bool, std::string)>>;
auto union_callback_demo = UnionCallbackDemo::Create();
union_callback_demo->Finally(
    base::BindOnce([](std::unique_ptr<UnionCallbackDemo> self) {
      LOG(INFO) << "NEOTIX: int=" << std::get<0>(self->GetResult<0>())
                << " bool=" << std::get<0>(self->GetResult<1>())
                << " string=" << std::get<1>(self->GetResult<1>());
    }));
union_callback_demo->GetCallback<0>().Run(110);
union_callback_demo->GetCallback<1>().Run(true, "springhack");