Skip to content

Commit 5aa4d7a

Browse files
ngotxicilion
authored andcommitted
events, feat: add setMaxListeners & getMaxListeners & defaultMaxListers support (#240)
* events, feat: add setMaxListeners & getMaxListeners & defaultMaxListeners support * events, feat: add newListener & removeListener event * events, fixbug: fix the global defaultMaxListeners shared between the different isolates. The defaultMaxListeners should belong to it's owen isolates. * events, refactor: rename defaultMaxListeners to m_defaultMaxListeners & init it in constructor
1 parent a88f9f8 commit 5aa4d7a

File tree

11 files changed

+441
-26
lines changed

11 files changed

+441
-26
lines changed

fibjs/include/Isolate.h

+2
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ class Isolate : public exlib::linkitem {
123123

124124
int32_t m_loglevel;
125125

126+
int32_t m_defaultMaxListeners;
127+
126128
bool m_interrupt;
127129
};
128130

fibjs/include/Trigger.h

+142-23
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,43 @@ class JSTrigger {
8787
return esa;
8888
}
8989

90-
inline int32_t putFunction(v8::Local<v8::Array> esa, v8::Local<v8::Function> func)
90+
inline result_t emitNewOrRemoveEvent(v8::Local<v8::Function> func, exlib::string ev, exlib::string type)
9191
{
92-
int32_t len = esa->Length();
92+
std::vector<v8::Local<v8::Value>> _args;
93+
_args.resize(2);
94+
bool b;
95+
96+
_args[0] = NewFromUtf8(ev);
97+
98+
v8::Local<v8::Value> _func = func->Get(NewFromUtf8("_func"));
99+
100+
if (_func->IsUndefined() || _func->IsNull())
101+
_args[1] = func;
102+
else
103+
_args[1] = _func;
104+
105+
return _emit(type, _args.data(), (int32_t)_args.size(), b);
106+
}
107+
108+
inline int32_t putFunction(v8::Local<v8::Array> esa, v8::Local<v8::Function> func, exlib::string ev)
109+
{
110+
result_t hr;
111+
hr = emitNewOrRemoveEvent(func, ev, "newListener");
112+
if (hr < 0)
113+
return hr;
93114

115+
int32_t len = esa->Length();
94116
esa->Set(len, func);
95-
return 1;
117+
return 0;
96118
}
97119

98-
inline int32_t prependPutFunction(v8::Local<v8::Array> esa, v8::Local<v8::Function> func)
120+
inline int32_t prependPutFunction(v8::Local<v8::Array> esa, v8::Local<v8::Function> func, exlib::string ev)
99121
{
122+
result_t hr;
123+
hr = emitNewOrRemoveEvent(func, ev, "newListener");
124+
if (hr < 0)
125+
return hr;
126+
100127
int32_t len = esa->Length();
101128
int32_t i;
102129

@@ -105,7 +132,7 @@ class JSTrigger {
105132
esa->Set(i, v);
106133
}
107134
esa->Set(0, func);
108-
return 1;
135+
return 0;
109136
}
110137

111138
inline void spliceOne(v8::Local<v8::Array> esa, int32_t index)
@@ -119,7 +146,7 @@ class JSTrigger {
119146
v8::Integer::New(isolate, len - 1));
120147
}
121148

122-
inline int32_t removeFunction(v8::Local<v8::Array> esa, v8::Local<v8::Function> func)
149+
inline int32_t removeFunction(v8::Local<v8::Array> esa, v8::Local<v8::Function> func, exlib::string ev)
123150
{
124151
if (esa.IsEmpty())
125152
return 0;
@@ -131,7 +158,11 @@ class JSTrigger {
131158
v8::Local<v8::Value> v = esa->Get(i);
132159
if (v->Equals(func)) {
133160
spliceOne(esa, i);
134-
return 1;
161+
result_t hr;
162+
hr = emitNewOrRemoveEvent(func, ev, "removeListener");
163+
if (hr < 0)
164+
return hr;
165+
return 0;
135166
}
136167
}
137168

@@ -166,7 +197,7 @@ class JSTrigger {
166197

167198
result_t on(exlib::string ev, v8::Local<v8::Function> func, v8::Local<v8::Object>& retVal)
168199
{
169-
putFunction(GetHiddenList(ev, true), func);
200+
putFunction(GetHiddenList(ev, true), func, ev);
170201
retVal = o;
171202
return 0;
172203
}
@@ -178,7 +209,7 @@ class JSTrigger {
178209

179210
result_t prependListener(exlib::string ev, v8::Local<v8::Function> func, v8::Local<v8::Object>& retVal)
180211
{
181-
prependPutFunction(GetHiddenList(ev, true), func);
212+
prependPutFunction(GetHiddenList(ev, true), func, ev);
182213
retVal = o;
183214
return 0;
184215
}
@@ -215,13 +246,14 @@ class JSTrigger {
215246

216247
result_t once(exlib::string ev, v8::Local<v8::Function> func, v8::Local<v8::Object>& retVal)
217248
{
218-
Isolate* isolate = Isolate::current();
219-
v8::Local<v8::Object> _data = v8::Object::New(isolate->m_isolate);
220-
_data->Set(isolate->NewFromUtf8("_func"), func);
221-
_data->Set(isolate->NewFromUtf8("_ev"), isolate->NewFromUtf8(ev));
249+
Isolate* _isolate = Isolate::current();
250+
v8::Local<v8::Object> _data = v8::Object::New(isolate);
251+
_data->Set(NewFromUtf8("_func"), func);
252+
_data->Set(NewFromUtf8("_ev"), NewFromUtf8(ev));
222253

223-
v8::Local<v8::Function> wrap = isolate->NewFunction("_onceWrap", _onceWrap, _data);
224-
putFunction(GetHiddenList(ev, true), wrap);
254+
v8::Local<v8::Function> wrap = _isolate->NewFunction("_onceWrap", _onceWrap, _data);
255+
wrap->Set(NewFromUtf8("_func"), func);
256+
putFunction(GetHiddenList(ev, true), wrap, ev);
225257

226258
retVal = o;
227259
return 0;
@@ -234,16 +266,16 @@ class JSTrigger {
234266

235267
result_t prependOnceListener(exlib::string ev, v8::Local<v8::Function> func, v8::Local<v8::Object>& retVal)
236268
{
237-
Isolate* isolate = Isolate::current();
238-
v8::Local<v8::Object> _data = v8::Object::New(isolate->m_isolate);
239-
_data->Set(isolate->NewFromUtf8("_func"), func);
240-
_data->Set(isolate->NewFromUtf8("_ev"), isolate->NewFromUtf8(ev));
269+
Isolate* _isolate = Isolate::current();
270+
v8::Local<v8::Object> _data = v8::Object::New(isolate);
271+
_data->Set(NewFromUtf8("_func"), func);
272+
_data->Set(NewFromUtf8("_ev"), NewFromUtf8(ev));
241273

242-
v8::Local<v8::Function> wrap = isolate->NewFunction("_onceWrap", _onceWrap, _data);
274+
v8::Local<v8::Function> wrap = _isolate->NewFunction("_onceWrap", _onceWrap, _data);
243275

244-
_data->Set(isolate->NewFromUtf8("_wrap"), wrap);
276+
_data->Set(NewFromUtf8("_wrap"), wrap);
245277

246-
prependPutFunction(GetHiddenList(ev, true), wrap);
278+
prependPutFunction(GetHiddenList(ev, true), wrap, ev);
247279

248280
retVal = o;
249281
return 0;
@@ -258,7 +290,7 @@ class JSTrigger {
258290
{
259291
v8::Local<v8::Array> esa = GetHiddenList(ev);
260292

261-
removeFunction(esa, func);
293+
removeFunction(esa, func, ev);
262294

263295
int32_t len = esa->Length();
264296

@@ -305,6 +337,47 @@ class JSTrigger {
305337
return 0;
306338
}
307339

340+
result_t setMaxListeners(int32_t n)
341+
{
342+
if(n < 0)
343+
return Runtime::setError("\"defaultMaxListeners\" must be a positive number");
344+
345+
o->SetPrivate(o->CreationContext(),
346+
v8::Private::ForApi(isolate, NewFromUtf8("_maxListeners")), v8::Integer::New(isolate, n));
347+
return 0;
348+
}
349+
350+
result_t getMaxListeners(int32_t& retVal)
351+
{
352+
Isolate* _isolate = Isolate::current();
353+
v8::Local<v8::Value> maxListeners = o->GetPrivate(o->CreationContext(),
354+
v8::Private::ForApi(isolate, NewFromUtf8("_maxListeners")))
355+
.ToLocalChecked();
356+
if (maxListeners->IsUndefined() || maxListeners->IsNull()) {
357+
retVal = _isolate->m_defaultMaxListeners;
358+
} else {
359+
GetArgumentValue(maxListeners, retVal, true);
360+
}
361+
return 0;
362+
}
363+
364+
static result_t set_defaultMaxListeners(int32_t newVal)
365+
{
366+
if(newVal < 0)
367+
return Runtime::setError("\"defaultMaxListeners\" must be a positive number");
368+
369+
Isolate* isolate = Isolate::current();
370+
isolate->m_defaultMaxListeners = newVal;
371+
return 0;
372+
}
373+
374+
static result_t get_defaultMaxListeners(int32_t& retVal)
375+
{
376+
Isolate* isolate = Isolate::current();
377+
retVal = isolate->m_defaultMaxListeners;
378+
return 0;
379+
}
380+
308381
result_t listeners(exlib::string ev, v8::Local<v8::Array>& retVal)
309382
{
310383
int32_t n = 0;
@@ -570,6 +643,52 @@ class JSTrigger {
570643

571644
static void s_setMaxListeners(const v8::FunctionCallbackInfo<v8::Value>& args)
572645
{
646+
JSTrigger t(args);
647+
648+
METHOD_ENTER();
649+
650+
METHOD_OVER(1, 1);
651+
652+
ARG(int32_t, 0);
653+
654+
t.setMaxListeners(v0);
655+
656+
METHOD_VOID();
657+
}
658+
659+
static void s_getMaxListeners(const v8::FunctionCallbackInfo<v8::Value>& args)
660+
{
661+
int32_t vr;
662+
JSTrigger t(args);
663+
664+
METHOD_ENTER();
665+
666+
METHOD_OVER(0, 0);
667+
668+
hr = t.getMaxListeners(vr);
669+
670+
METHOD_RETURN();
671+
}
672+
673+
static void s_get_defaultMaxListeners(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args)
674+
{
675+
int32_t vr;
676+
677+
PROPERTY_ENTER();
678+
679+
hr = get_defaultMaxListeners(vr);
680+
681+
METHOD_RETURN();
682+
}
683+
684+
static void s_set_defaultMaxListeners(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args)
685+
{
686+
PROPERTY_ENTER();
687+
PROPERTY_VAL(int32_t);
688+
689+
hr = set_defaultMaxListeners(v0);
690+
691+
PROPERTY_SET_LEAVE();
573692
}
574693

575694
static void s_listeners(const v8::FunctionCallbackInfo<v8::Value>& args)

fibjs/include/WebSocket.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,11 @@ class WebSocket : public WebSocket_base {
131131
}
132132
virtual result_t setMaxListeners(int32_t n)
133133
{
134-
return 0;
134+
return object_base::setMaxListeners(n);
135+
}
136+
virtual result_t getMaxListeners(int32_t& retVal)
137+
{
138+
return object_base::getMaxListeners(retVal);
135139
}
136140
virtual result_t listeners(exlib::string ev, v8::Local<v8::Array>& retVal)
137141
{

fibjs/include/ifs/EventEmitter.h

+47-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class EventEmitter_base : public object_base {
2222
public:
2323
// EventEmitter_base
2424
static result_t _new(obj_ptr<EventEmitter_base>& retVal, v8::Local<v8::Object> This = v8::Local<v8::Object>());
25+
static result_t get_defaultMaxListeners(int32_t& retVal);
26+
static result_t set_defaultMaxListeners(int32_t newVal);
2527
virtual result_t on(exlib::string ev, v8::Local<v8::Function> func, v8::Local<v8::Object>& retVal) = 0;
2628
virtual result_t on(v8::Local<v8::Object> map, v8::Local<v8::Object>& retVal) = 0;
2729
virtual result_t addListener(exlib::string ev, v8::Local<v8::Function> func, v8::Local<v8::Object>& retVal) = 0;
@@ -40,6 +42,7 @@ class EventEmitter_base : public object_base {
4042
virtual result_t removeListener(v8::Local<v8::Object> map, v8::Local<v8::Object>& retVal) = 0;
4143
virtual result_t removeAllListeners(v8::Local<v8::Array> evs, v8::Local<v8::Object>& retVal) = 0;
4244
virtual result_t setMaxListeners(int32_t n) = 0;
45+
virtual result_t getMaxListeners(int32_t& retVal) = 0;
4346
virtual result_t listeners(exlib::string ev, v8::Local<v8::Array>& retVal) = 0;
4447
virtual result_t listenerCount(exlib::string ev, int32_t& retVal) = 0;
4548
virtual result_t eventNames(v8::Local<v8::Array>& retVal) = 0;
@@ -51,6 +54,8 @@ class EventEmitter_base : public object_base {
5154

5255
public:
5356
static void s__new(const v8::FunctionCallbackInfo<v8::Value>& args);
57+
static void s_get_defaultMaxListeners(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args);
58+
static void s_set_defaultMaxListeners(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
5459
static void s_on(const v8::FunctionCallbackInfo<v8::Value>& args);
5560
static void s_addListener(const v8::FunctionCallbackInfo<v8::Value>& args);
5661
static void s_prependListener(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -60,6 +65,7 @@ class EventEmitter_base : public object_base {
6065
static void s_removeListener(const v8::FunctionCallbackInfo<v8::Value>& args);
6166
static void s_removeAllListeners(const v8::FunctionCallbackInfo<v8::Value>& args);
6267
static void s_setMaxListeners(const v8::FunctionCallbackInfo<v8::Value>& args);
68+
static void s_getMaxListeners(const v8::FunctionCallbackInfo<v8::Value>& args);
6369
static void s_listeners(const v8::FunctionCallbackInfo<v8::Value>& args);
6470
static void s_listenerCount(const v8::FunctionCallbackInfo<v8::Value>& args);
6571
static void s_eventNames(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -80,15 +86,20 @@ inline ClassInfo& EventEmitter_base::class_info()
8086
{ "removeListener", s_removeListener, false },
8187
{ "removeAllListeners", s_removeAllListeners, false },
8288
{ "setMaxListeners", s_setMaxListeners, false },
89+
{ "getMaxListeners", s_getMaxListeners, false },
8390
{ "listeners", s_listeners, false },
8491
{ "listenerCount", s_listenerCount, false },
8592
{ "eventNames", s_eventNames, false },
8693
{ "emit", s_emit, false }
8794
};
8895

96+
static ClassData::ClassProperty s_property[] = {
97+
{ "defaultMaxListeners", s_get_defaultMaxListeners, s_set_defaultMaxListeners, true }
98+
};
99+
89100
static ClassData s_cd = {
90101
"EventEmitter", false, s__new, NULL,
91-
ARRAYSIZE(s_method), s_method, 0, NULL, 0, NULL, NULL, NULL,
102+
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, NULL, NULL,
92103
&object_base::class_info()
93104
};
94105

@@ -116,6 +127,27 @@ void EventEmitter_base::__new(const T& args)
116127
CONSTRUCT_RETURN();
117128
}
118129

130+
inline void EventEmitter_base::s_get_defaultMaxListeners(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args)
131+
{
132+
int32_t vr;
133+
134+
PROPERTY_ENTER();
135+
136+
hr = get_defaultMaxListeners(vr);
137+
138+
METHOD_RETURN();
139+
}
140+
141+
inline void EventEmitter_base::s_set_defaultMaxListeners(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args)
142+
{
143+
PROPERTY_ENTER();
144+
PROPERTY_VAL(int32_t);
145+
146+
hr = set_defaultMaxListeners(v0);
147+
148+
PROPERTY_SET_LEAVE();
149+
}
150+
119151
inline void EventEmitter_base::s_on(const v8::FunctionCallbackInfo<v8::Value>& args)
120152
{
121153
v8::Local<v8::Object> vr;
@@ -319,6 +351,20 @@ inline void EventEmitter_base::s_setMaxListeners(const v8::FunctionCallbackInfo<
319351
METHOD_VOID();
320352
}
321353

354+
inline void EventEmitter_base::s_getMaxListeners(const v8::FunctionCallbackInfo<v8::Value>& args)
355+
{
356+
int32_t vr;
357+
358+
METHOD_INSTANCE(EventEmitter_base);
359+
METHOD_ENTER();
360+
361+
METHOD_OVER(0, 0);
362+
363+
hr = pInst->getMaxListeners(vr);
364+
365+
METHOD_RETURN();
366+
}
367+
322368
inline void EventEmitter_base::s_listeners(const v8::FunctionCallbackInfo<v8::Value>& args)
323369
{
324370
v8::Local<v8::Array> vr;

fibjs/include/ifs/EventEmitter.idl

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ interface EventEmitter : object
1212
/*! @brief 构造函数 */
1313
EventEmitter();
1414

15+
/*! @brief 默认全局最大监听器数 */
16+
static Integer defaultMaxListeners;
17+
1518
/*! @brief 绑定一个事件处理函数到对象
1619
@param ev 指定事件的名称
1720
@param func 指定事件处理函数
@@ -128,6 +131,10 @@ interface EventEmitter : object
128131
*/
129132
setMaxListeners(Integer n);
130133

134+
/* 获取监听器的默认限制的数量,仅用于兼容
135+
*/
136+
Integer getMaxListeners();
137+
131138
/*! @brief 查询对象指定事件的监听器数组
132139
@param ev 指定事件的名称
133140
@return 返回指定事件的监听器数组

0 commit comments

Comments
 (0)