File: event_handler.cpp

package info (click to toggle)
libfilezilla 0.54.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,504 kB
  • sloc: cpp: 31,105; sh: 4,241; makefile: 375; xml: 37
file content (108 lines) | stat: -rw-r--r-- 2,355 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "libfilezilla/event_handler.hpp"

#include <cassert>

namespace fz {

event_handler::event_handler(event_loop& loop)
	: event_loop_(loop)
{
}

event_handler::event_handler(event_handler const& h)
	: event_loop_(h.event_loop_)
{
}

event_handler::event_handler(event_handler & h, event_handler_option)
	: event_loop_(h.event_loop_)
{
	scoped_lock l(event_loop_.sync_);
	if (h.removing_) {
		removing_ = true;
	}
	else {
		next_ = h.child_;
		h.child_ = this;
		parent_ = &h;
	}
}

event_handler::~event_handler()
{
	assert(removing_); // To avoid races, the base class must have removed us already

	// No need to lock here, the subtree is inert

	// Split the children
	while (child_) {
		child_->parent_ = nullptr;
		auto n = child_->next_;
		child_->next_ = nullptr;
		child_ = n;
	}
}

void event_handler::remove_from_parent()
{
	if (parent_) {
		// By construction, we only have siblings if there is a parent.

		if (parent_->child_ == this) {
			// We're first in the list
			parent_->child_ = next_;
		}
		else {
			auto* cur = parent_->child_;
			while (cur->next_ != this) {
				cur = cur->next_;
			}
			cur->next_ = next_;
		}
		parent_ = nullptr;
	}
}

void event_handler::remove_handler()
{
	event_loop_.remove_handler(this);
}

timer_id event_handler::add_timer(duration const& interval, bool one_shot)
{
	return event_loop_.add_timer(this, monotonic_clock::now() + interval, one_shot ? duration() : interval);
}

timer_id event_handler::add_timer(monotonic_clock const& deadline, duration const& interval)
{
	return event_loop_.add_timer(this, deadline, interval);
}

void event_handler::stop_timer(timer_id id)
{
	event_loop_.stop_timer(id);
}

timer_id event_handler::stop_add_timer(timer_id id, duration const& interval, bool one_shot)
{
	return event_loop_.stop_add_timer(id, this, monotonic_clock::now() + interval, one_shot ? duration() : interval);
}

timer_id event_handler::stop_add_timer(timer_id id, monotonic_clock const& deadline, duration const& interval)
{
	return event_loop_.stop_add_timer(id, this, deadline, interval);
}

void event_handler::remove_events(event_source const* const source)
{
	auto event_filter = [&](event_base& ev) -> bool {
			auto sev = dynamic_cast<event_with_source_base*>(&ev);
			if (sev) {
				return sev->source() == source;
			}
			return false;
		};
	filter_events(event_filter);
}

}