Skip to content

Commit

Permalink
Create a shared event dispatcher for instance, so we can save some re…
Browse files Browse the repository at this point in the history
…source

Every EventDispatcher will create a new pipe, which is not really need
if EventDispatcher is shared.
  • Loading branch information
wengxt committed Apr 21, 2024
1 parent 6824c95 commit c069a4c
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 21 deletions.
10 changes: 9 additions & 1 deletion src/lib/fcitx/instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <memory>
#include <stdexcept>
#include <unordered_map>
#include <utility>
Expand All @@ -18,6 +19,7 @@
#include "fcitx-config/iniparser.h"
#include "fcitx-utils/capabilityflags.h"
#include "fcitx-utils/event.h"
#include "fcitx-utils/eventdispatcher.h"
#include "fcitx-utils/i18n.h"
#include "fcitx-utils/log.h"
#include "fcitx-utils/misc.h"
Expand Down Expand Up @@ -641,9 +643,10 @@ Instance::Instance(int argc, char **argv) {
}

// we need fork before this
d_ptr.reset(new InstancePrivate(this));
d_ptr = std::make_unique<InstancePrivate>(this);
FCITX_D();
d->arg_ = arg;
d->eventDispatcher_.attach(&d->eventLoop_);
d->addonManager_.setInstance(this);
d->addonManager_.setAddonOptions(arg.addonOptions_);
d->icManager_.setInstance(this);
Expand Down Expand Up @@ -1519,6 +1522,11 @@ EventLoop &Instance::eventLoop() {
return d->eventLoop_;
}

EventDispatcher &Instance::eventDispatcher() {
FCITX_D();
return d->eventDispatcher_;
}

InputContextManager &Instance::inputContextManager() {
FCITX_D();
return d->icManager_;
Expand Down
10 changes: 10 additions & 0 deletions src/lib/fcitx/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <fcitx/event.h>
#include <fcitx/globalconfig.h>
#include <fcitx/text.h>
#include "fcitx-utils/eventdispatcher.h"
#include "fcitxcore_export.h"

#define FCITX_INVALID_COMPOSE_RESULT 0xffffffff
Expand Down Expand Up @@ -154,6 +155,15 @@ class FCITXCORE_EXPORT Instance : public ConnectableObject {
/// Get the fcitx event loop.
EventLoop &eventLoop();

/**
* Return a shared event dispatcher that is already attached to instance's
* event loop.
*
* @return shared event dispatcher.
* @since 5.1.9
*/
EventDispatcher &eventDispatcher();

/// Get the addon manager.
AddonManager &addonManager();

Expand Down
2 changes: 2 additions & 0 deletions src/lib/fcitx/instance_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <string>
#include <unordered_map>
#include "fcitx-utils/event.h"
#include "fcitx-utils/eventdispatcher.h"
#include "fcitx-utils/handlertable.h"
#include "fcitx-utils/misc.h"
#include "fcitx-utils/trackableobject.h"
Expand Down Expand Up @@ -161,6 +162,7 @@ class InstancePrivate : public QPtrHolder<Instance> {
: InputMethodMode::PhysicalKeyboard;

EventLoop eventLoop_;
EventDispatcher eventDispatcher_;
std::unique_ptr<EventSourceIO> signalPipeEvent_;
std::unique_ptr<EventSourceTime> preloadInputMethodEvent_;
std::unique_ptr<EventSource> exitEvent_;
Expand Down
7 changes: 2 additions & 5 deletions src/modules/clipboard/waylandclipboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ void DataOffer::receiveDataForMime(const std::string &mime,

DataDevice::DataDevice(WaylandClipboard *clipboard,
wayland::ZwlrDataControlDeviceV1 *device)
: clipboard_(clipboard), device_(device), thread_(clipboard_->eventLoop()) {
: clipboard_(clipboard), device_(device),
thread_(clipboard_->parent()->instance()->eventDispatcher()) {
conns_.emplace_back(device_->dataOffer().connect(
[this](wayland::ZwlrDataControlOfferV1 *offer) {
new DataOffer(offer, *clipboard_->parent()
Expand Down Expand Up @@ -271,10 +272,6 @@ void WaylandClipboard::refreshSeat() {
}
}

EventLoop *WaylandClipboard::eventLoop() {
return &parent_->instance()->eventLoop();
}

void WaylandClipboard::setClipboard(const std::string &str, bool password) {
parent_->setClipboardV2(name_, str, password);
}
Expand Down
6 changes: 3 additions & 3 deletions src/modules/clipboard/waylandclipboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ struct DataOfferTask {

class DataReaderThread {
public:
DataReaderThread(EventLoop *main) { dispatcherToMain_.attach(main); }
DataReaderThread(EventDispatcher &dispatcherToMain)
: dispatcherToMain_(dispatcherToMain) {}

~DataReaderThread() {
if (thread_ && thread_->joinable()) {
Expand All @@ -65,7 +66,7 @@ class DataReaderThread {
private:
void realRun();

EventDispatcher dispatcherToMain_;
EventDispatcher &dispatcherToMain_;
EventDispatcher dispatcherToWorker_;
std::unique_ptr<std::thread> thread_;
// Value only handled by the reader thread.
Expand Down Expand Up @@ -121,7 +122,6 @@ class WaylandClipboard {

void setClipboard(const std::string &str, bool password);
void setPrimary(const std::string &str, bool password);
EventLoop *eventLoop();
auto display() const { return display_; }
auto parent() const { return parent_; }

Expand Down
13 changes: 6 additions & 7 deletions src/modules/wayland/waylandeventreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
namespace fcitx {

WaylandEventReader::WaylandEventReader(WaylandConnection *conn)
: module_(conn->parent()), conn_(conn), display_(*conn_->display()) {
: module_(conn->parent()), conn_(conn), display_(*conn_->display()),
dispatcherToMain_(module_->instance()->eventDispatcher()) {
postEvent_ = module_->instance()->eventLoop().addPostEvent(
[this](EventSource *source) {
if (wl_display_get_error(display_)) {
Expand All @@ -24,7 +25,6 @@ WaylandEventReader::WaylandEventReader(WaylandConnection *conn)
display_.flush();
return true;
});
dispatcherToMain_.attach(&conn->parent()->instance()->eventLoop());
// Actively trigger an initial dispatch so we can make sure:
// 1. depending even before this WaylandEventReader are handled.
// 2. prepare_read is called.
Expand All @@ -33,8 +33,6 @@ WaylandEventReader::WaylandEventReader(WaylandConnection *conn)
std::make_unique<std::thread>(&WaylandEventReader::runThread, this);
}
WaylandEventReader::~WaylandEventReader() {
// Prevent that dispatcherToMain_ to deliver removeConnection.
dispatcherToMain_.detach();
if (thread_->joinable()) {
quit();
thread_->join();
Expand Down Expand Up @@ -110,9 +108,10 @@ void WaylandEventReader::quit() {

// Make sure the connection will be removed.
// The destructor will join the reader thread so it's ok.
dispatcherToMain_.schedule([module = module_, name = conn_->name()]() {
module->removeConnection(name);
});
dispatcherToMain_.scheduleWithContext(
this->watch(), [module = module_, name = conn_->name()]() {
module->removeConnection(name);
});
}

void WaylandEventReader::dispatch() {
Expand Down
5 changes: 3 additions & 2 deletions src/modules/wayland/waylandeventreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
#include <thread>
#include "fcitx-utils/event.h"
#include "fcitx-utils/eventdispatcher.h"
#include "fcitx-utils/trackableobject.h"
#include "display.h"

namespace fcitx {

class WaylandConnection;
class WaylandModule;

class WaylandEventReader {
class WaylandEventReader : public TrackableObject<WaylandEventReader> {
public:
WaylandEventReader(WaylandConnection *conn);
~WaylandEventReader();
Expand All @@ -34,7 +35,7 @@ class WaylandEventReader {
WaylandModule *module_;
WaylandConnection *conn_;
wayland::Display &display_;
EventDispatcher dispatcherToMain_;
EventDispatcher &dispatcherToMain_;
EventDispatcher dispatcherToWorker_;
std::unique_ptr<EventSource> postEvent_;

Expand Down
4 changes: 2 additions & 2 deletions src/modules/xcb/xcbeventreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
#include "xcbmodule.h"

namespace fcitx {
XCBEventReader::XCBEventReader(XCBConnection *conn) : conn_(conn) {
XCBEventReader::XCBEventReader(XCBConnection *conn)
: conn_(conn), dispatcherToMain_(conn->instance()->eventDispatcher()) {
postEvent_ =
conn->instance()->eventLoop().addPostEvent([this](EventSource *source) {
if (xcb_connection_has_error(conn_->connection())) {
Expand All @@ -22,7 +23,6 @@ XCBEventReader::XCBEventReader(XCBConnection *conn) : conn_(conn) {
xcb_flush(conn_->connection());
return true;
});
dispatcherToMain_.attach(&conn->instance()->eventLoop());
thread_ = std::make_unique<std::thread>(&XCBEventReader::runThread, this);
}

Expand Down
2 changes: 1 addition & 1 deletion src/modules/xcb/xcbeventreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class XCBEventReader {
void run();
bool onIOEvent(IOEventFlags flags);
XCBConnection *conn_;
EventDispatcher dispatcherToMain_;
EventDispatcher &dispatcherToMain_;
EventDispatcher dispatcherToWorker_;
bool hadError_ = false;
std::unique_ptr<EventSource> deferEvent_;
Expand Down

0 comments on commit c069a4c

Please sign in to comment.