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

推荐订阅源

Y
Y Combinator Blog
美团技术团队
H
Hacker News: Front Page
Spread Privacy
Spread Privacy
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tenable Blog
Simon Willison's Weblog
Simon Willison's Weblog
T
The Exploit Database - CXSecurity.com
Cisco Talos Blog
Cisco Talos Blog
A
Arctic Wolf
C
CXSECURITY Database RSS Feed - CXSecurity.com
Application and Cybersecurity Blog
Application and Cybersecurity Blog
A
About on SuperTechFans
F
Fortinet All Blogs
量子位
GbyAI
GbyAI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Hacker News
The Hacker News
AWS News Blog
AWS News Blog
Forbes - Security
Forbes - Security
Help Net Security
Help Net Security
I
InfoQ
有赞技术团队
有赞技术团队
W
WeLiveSecurity
Google DeepMind News
Google DeepMind News
Engineering at Meta
Engineering at Meta
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Secure Thoughts
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Webroot Blog
Webroot Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
C
Check Point Blog
T
Troy Hunt's Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
Latest news
Latest news
P
Proofpoint News Feed
Jina AI
Jina AI
Last Week in AI
Last Week in AI
Martin Fowler
Martin Fowler
雷峰网
雷峰网
博客园 - Franky
L
LangChain Blog
罗磊的独立博客
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
D
Docker
G
GRAHAM CLULEY
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

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");