// Atomically send multiple data. // @iov Array of <iovec>. // @iovcnt Number of elements in `iov`. // @flush If `true`, the kernel send buffer will be flushed. // // This function sends a chunk of data atomically. The reactor // thread should not call this, or it may be blocked forever. // // @return `true` if this socket is valid, `false` otherwise. bool sendv(const iovec* iov, int iovcnt, bool flush=false) { if( iovcnt >= MAX_IOVCNT ) throw std::logic_error("<tcp_socket::sendv> too many iovec."); lock_guard g(m_lock); if( ! _sendv(iov, iovcnt, g) ) return false; if( flush && empty() ) _flush(); return true; }
static oop ArrayedCollection__with_(oop v__closure, oop v_stateful_self, oop v_self, oop v_anObject) { _enter(&__info6); oop _1= 0; oop _2= 0; oop _3= 0; _line(47); _1= v_self; _2= l_7; _line(49); _1=_sendv(s_new_, 2, _1, _2); _2= l_7; _3= v_anObject; _line(50); _sendv(s_at_put_, 3, _1, _2, _3); _1=_sendv(s_yourself, 1, _1); _leave(); return _1; _leave(); }
static oop b_16(oop v__closure, oop v__self, oop v_elt, oop v_ind) { _enter(&__info16); oop _1= 0; oop _2= 0; oop _3= 0; oop _4= 0; _line(82); _1= ((oop *)((struct t_BlockClosure *)((struct t_BlockClosure *)v__self)->v_state))[1]; /* answer */ _2= v_ind; _3= ((oop *)((struct t_BlockClosure *)((struct t_BlockClosure *)v__self)->v_state))[2]; /* unaryBlock */ _4= v_elt; _line(82); _3=_sendv(s_value_, 2, _3, _4); _line(82); _1=_sendv(s_at_put_, 3, _1, _2, _3); _leave(); return _1; _leave(); }
static oop ArrayedCollection___5fsize(oop v__closure, oop v_stateful_self, oop v_self) { _enter(&__info17); oop _1= 0; _line(86); _1= ((struct t_ArrayedCollection *)v_stateful_self)->v_size; _line(88); _1=_sendv(s__5fintegerValue, 1, _1); _leave(); return _1; _leave(); }
static oop ArrayedCollection__collect_(oop v__closure, oop v_stateful_self, oop v_self, oop v_unaryBlock) { _enter(&__info15); oop _state1= _sendv(s_new_5f_, 2, v__vector, 3); oop _1= 0; oop _2= 0; ((oop *)_state1)[2]= v_unaryBlock; _line(78); _1= v_self; _line(81); _1=_sendv(s_species, 1, _1); _2= v_self; _line(81); _2=_sendv(s_size, 1, _2); _line(81); _1=_sendv(s_new_, 2, _1, _2); ((oop *)_state1)[1]= _1; /* answer */ _1= v_self; /* Scope('elt'->ArgumentVariableNode 'ind'->ArgumentVariableNode) */ /* Scope('size'->SlotVariableNode 'self'->ArgumentVariableNode 'answer'->TemporaryVariableNode 'unaryBlock'->ArgumentVariableNode 'stateful_self'->ArgumentVariableNode) */ /* nil */ /* 2 */ /* 1 */ _2= _sendv(s_function_5f_arity_5f_outer_state_nlr_5f_, 6, v_BlockClosure, (oop)b_16, 2, 0, ((oop *)_state1), 0); _line(82); _1=_sendv(s_doWithIndex_, 2, _1, _2); _1= ((oop *)_state1)[1]; /* answer */ _leave(); return _1; _leave(); }
bool ServiceManager::notifyByObject(PACKET& packet, Object* obj){ static thread_local char bs[CACHE_SIZE] ={0}; int64_t len =CACHE_SIZE; char* data =object_to_bytes(bs, obj, len); if(len < 0){ return false; } const bool ret =_sendv(SENDV_FLAG_NOTIFY, 0, packet, data, len); if(data && data != bs){ DEALLOCATE(data); } return ret; }
static oop StaticBlockClosure__arity(oop v__closure, oop v_stateful_self, oop v_self) { _enter(&__info2); oop _1= 0; oop _2= 0; _line(42); _1= v_SmallInteger; _2= ((struct t_StaticBlockClosure *)v_stateful_self)->v__arity; _line(42); _1=_sendv(s_value_5f_, 2, _1, _2); _leave(); return _1; _leave(); }
static oop ArrayedCollection__new_(oop v__closure, oop v_stateful_self, oop v_self, oop v_anInteger) { _enter(&__info1); oop _1= 0; oop _2= 0; _line(25); _1= v_self; _line(27); _1=_superv(v_SequenceableCollection, s_new, 1, _1); _2= v_anInteger; _line(27); _1=_sendv(s_initialize_, 2, _1, _2); _leave(); return _1; _leave(); }
static oop b_12(oop v__closure, oop v__self, oop v_e, oop v_i) { _enter(&__info12); oop _1= 0; oop _2= 0; oop _3= 0; _line(65); _1= ((oop *)((struct t_BlockClosure *)((struct t_BlockClosure *)v__self)->v_state))[1]; /* self */ _2= v_i; _3= v_e; _line(65); _1=_sendv(s_at_put_, 3, _1, _2, _3); _leave(); return _1; _leave(); }
// Atomically send multiple data, then close the socket. // @iov Array of <iovec>. // @iovcnt Number of elements in `iov`. // // This function sends a chunk of data atomically. The socket // will be closed after data are sent. The reactor thread should // not call this, or it may be blocked forever. // // @return `true` if this socket is valid, `false` otherwise. bool sendv_close(const iovec* iov, int iovcnt) { if( iovcnt >= MAX_IOVCNT ) throw std::logic_error("<tcp_socket::sendv> too many iov."); lock_guard g(m_lock); if( ! _sendv(iov, iovcnt, g) ) return false; m_shutdown = true; if( empty() ) { _flush(); g.unlock(); invalidate_and_close(); return true; } g.unlock(); m_cond_write.notify_all(); return true; }
static oop ArrayedCollection__byteSize(oop v__closure, oop v_stateful_self, oop v_self) { _enter(&__info14); oop _1= 0; oop _2= 0; _line(73); _1= ((struct t_ArrayedCollection *)v_stateful_self)->v_size; _2= v_self; _line(75); _2=_sendv(s_elementSize, 1, _2); { int _l= (long)_1 >> 1; int _r= (long)_2 >> 1; int _s= (_l * _r); if ((1 & (long)_1 & (long)_2) && ((_r == 0) || (_s / _r == _l)) && ((_s ^ (_s << 1)) >= 0)) _1= (oop)(long)(_s << 1 | 1); else _1= _sendv(s__2a, 2, _1, _2); } _leave(); return _1; _leave(); }
static oop StaticBlockClosure__value_value_value_value_value_(oop v__closure, oop v_stateful_self, oop v_self, oop v_a, oop v_b, oop v_c, oop v_d, oop v_e) { _enter(&__info17); oop _1= 0; oop _2= 0; _line(81); { # define self ((struct t_StaticBlockClosure *)v_self) if ((long)self->v__arity == 5) return ((_imp_t)(self->v__function))(0, v_self, v_a, v_b, v_c, v_d, v_e); # undef self } _1= 0; _1= v_self; _2= l_18; _line(84); _1=_sendv(s_errorArgumentCount_, 2, _1, _2); _leave(); return _1; _leave(); }
static oop StaticBlockClosure__whileTrue(oop v__closure, oop v_stateful_self, oop v_self) { _enter(&__info19); oop _1= 0; _line(89); /* whileTrue: */ goto _l2; _l1:; { _1= v_nil; } _l2:; { _1= v_self; _line(91); _1=_sendv(s_value, 1, _1); } if (_1) goto _l1; _1= 0; _1= v_self; _leave(); return _1; _leave(); }
static oop StaticBlockClosure__whileFalse(oop v__closure, oop v_stateful_self, oop v_self) { _enter(&__info21); oop _1= 0; _line(102); /* whileFalse: */ goto _l5; _l4:; { _1= v_nil; } _l5:; { _1= v_self; _line(104); _1=_sendv(s_value, 1, _1); } if (!_1) goto _l4; _1= 0; _1= v_self; _leave(); return _1; _leave(); }
static oop StaticBlockClosure__repeat(oop v__closure, oop v_stateful_self, oop v_self) { _enter(&__info23); oop _1= 0; _line(115); /* whileTrue: */ goto _l8; _l7:; { _1= v_self; _line(117); _1=_sendv(s_value, 1, _1); } _l8:; { _1= v_true; } if (_1) goto _l7; _1= 0; _1= v_self; _leave(); return _1; _leave(); }
bool ServiceManager::reply(PACKET& packet, void* body, const int64_t body_len){ return _sendv(SENDV_FLAG_REPLY, 0, packet, body, body_len); }
void __id__init__BlockClosure(struct __libid *__libid) { if (_libid) return; if (!(_libid= __libid)) { fprintf(stderr, "init _libid %p\n", __libid); abort(); } # define GC_add_roots _libid->gc_addRoots GC_INIT(); { struct _Selector *s= 0; for (s= _Selectors; s->name; ++s) *s->addr= _libid->intern(s->name); } _enter(&__info); _libid->infos(&__info, &__info1); _sendv(s__5fimport_, 3, _libid->_object, "Object", "__id__init__Object"); v__object= _libid->import("_object"); v_Object= _libid->import("Object"); v_UndefinedObject= _libid->import("UndefinedObject"); v_StaticBlockClosure= _libid->import("StaticBlockClosure"); v_BlockClosure= _libid->import("BlockClosure"); v_Magnitude= _libid->import("Magnitude"); v_Number= _libid->import("Number"); v_Integer= _libid->import("Integer"); v_SmallInteger= _libid->import("SmallInteger"); v_LargePositiveInteger= _libid->import("LargePositiveInteger"); v_Collection= _libid->import("Collection"); v_SequenceableCollection= _libid->import("SequenceableCollection"); v_ArrayedCollection= _libid->import("ArrayedCollection"); v_Array= _libid->import("Array"); v_WordArray= _libid->import("WordArray"); v_ByteArray= _libid->import("ByteArray"); v_String= _libid->import("String"); v_ImmutableString= _libid->import("ImmutableString"); v_nil= _libid->import("nil"); v_true= _libid->import("true"); _libid->method(v_StaticBlockClosure, s_function_5f_arity_5f_, (_imp_t)StaticBlockClosure__function_5f_arity_5f_); _libid->method(v_StaticBlockClosure, s_arity, (_imp_t)StaticBlockClosure__arity); l_4= _sendv(s_size_5f_value_5f_, 3, v_ImmutableString, 19, "this block expects "); l_5= _sendv(s_size_5f_value_5f_, 3, v_ImmutableString, 25, " arguments (invoked with "); l_6= _sendv(s_size_5f_value_5f_, 3, v_ImmutableString, 1, ")"); _libid->method(v_StaticBlockClosure, s_errorArgumentCount_, (_imp_t)StaticBlockClosure__errorArgumentCount_); l_8= _sendv(s_value_5f_, 2, v_SmallInteger, 0); _libid->method(v_StaticBlockClosure, s_value, (_imp_t)StaticBlockClosure__value); l_10= _sendv(s_value_5f_, 2, v_SmallInteger, 1); _libid->method(v_StaticBlockClosure, s_value_, (_imp_t)StaticBlockClosure__value_); l_12= _sendv(s_value_5f_, 2, v_SmallInteger, 1); _libid->method(v_StaticBlockClosure, s_value_value_, (_imp_t)StaticBlockClosure__value_value_); l_14= _sendv(s_value_5f_, 2, v_SmallInteger, 1); _libid->method(v_StaticBlockClosure, s_value_value_value_, (_imp_t)StaticBlockClosure__value_value_value_); l_16= _sendv(s_value_5f_, 2, v_SmallInteger, 1); _libid->method(v_StaticBlockClosure, s_value_value_value_value_, (_imp_t)StaticBlockClosure__value_value_value_value_); l_18= _sendv(s_value_5f_, 2, v_SmallInteger, 1); _libid->method(v_StaticBlockClosure, s_value_value_value_value_value_, (_imp_t)StaticBlockClosure__value_value_value_value_value_); _libid->method(v_StaticBlockClosure, s_whileTrue, (_imp_t)StaticBlockClosure__whileTrue); _libid->method(v_StaticBlockClosure, s_whileTrue_, (_imp_t)StaticBlockClosure__whileTrue_); _libid->method(v_StaticBlockClosure, s_whileFalse, (_imp_t)StaticBlockClosure__whileFalse); _libid->method(v_StaticBlockClosure, s_whileFalse_, (_imp_t)StaticBlockClosure__whileFalse_); _libid->method(v_StaticBlockClosure, s_repeat, (_imp_t)StaticBlockClosure__repeat); _libid->method(v_BlockClosure, s_function_5f_arity_5f_outer_state_nlr_5f_, (_imp_t)BlockClosure__function_5f_arity_5f_outer_state_nlr_5f_); _leave(); }
bool ServiceManager::replyByObject(PACKET& packet, Object* obj){ return _sendv(SENDV_FLAG_REPLY, 0, packet, obj); }
bool ServiceManager::_sendv(const int64_t flag, Requestor* requestor, PACKET& packet, Object* obj){ packet.option |= OPT_BODY_IS_OBJECT_POINTER; return _sendv(flag, requestor, packet, reinterpret_cast< void* >(&obj), sizeof(obj)); }
bool ServiceManager::notify(PACKET& packet, void* body, const int64_t body_len){ return _sendv(SENDV_FLAG_NOTIFY, 0, packet, body, body_len); }
bool ServiceManager::requestByObject(Requestor* requestor, PACKET& packet, Object* obj){ return _sendv(SENDV_FLAG_REQUEST, requestor, packet, obj); }
/** Dispatcher **/ bool ServiceManager::request(Requestor* requestor, PACKET& packet, void* body, const int64_t body_len){ return _sendv(SENDV_FLAG_REQUEST, requestor, packet, body, body_len); }