ret ThreadSwitch::init(IEventPoll* poll) { if_return(nullptr_t == poll, ret_args_error); this->event_fd_ = ::eventfd(0, EFD_NONBLOCK); if_return(-1 == this->event_fd_, ret_fail); return __success(poll->set_event_listener(this->event_fd_, event_read, callback_key_)); }
ret TcpConnection::send_buffer(const byte* _buffer, int _size) { if_return(nullptr_t == _buffer || 0 >= _size, ret_fail); if_return(status_establish != this->connection_status_ || !tcp_server_, ret_fail); __sp<ITcpProtocol> _protocol; if_return(!__success(this->tcp_server_->get_protocol(&_protocol)) || !_protocol, ret_fail); return _protocol->encode(_buffer, _size, this->connection_self_); }
ret TcpConnection::get_peer_info(std::string* _addr, int* _port) { if_return(nullptr_t == _addr && nullptr_t == _port, ret_args_error); if_return(status_establish != this->connection_status_ && status_closing != this->connection_status_, ret_fail); bool _use_ipv6 = false; this->tcp_server_->use_ipv6(&_use_ipv6); if (_use_ipv6) { struct sockaddr_in6 _sockaddr; memset(&_sockaddr, 0, sizeof(struct sockaddr_in6)); socklen_t _addr_len = sizeof(struct sockaddr_in6); if_return(0 != ::getpeername(this->fd_, (sockaddr*)&_sockaddr, &_addr_len), ret_fail); if (nullptr_t != _port) { *_port = (int)ntohs(_sockaddr.sin6_port); } if (nullptr_t != _addr) { char _ip_string[40] = {0}; uint8_t* _ia = _sockaddr.sin6_addr.s6_addr; sprintf(_ip_string, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", _ia[0], _ia[1], _ia[2], _ia[3], _ia[4], _ia[5], _ia[6], _ia[7], _ia[8], _ia[9], _ia[10], _ia[11], _ia[12], _ia[13], _ia[14], _ia[15]); *_addr = _ip_string; } } else { struct sockaddr_in _sockaddr; memset(&_sockaddr, 0, sizeof(struct sockaddr_in)); socklen_t _addr_len = sizeof(struct sockaddr_in); if_return(0 != ::getpeername(this->fd_, (sockaddr*)&_sockaddr, &_addr_len), ret_fail); if (nullptr_t != _port) { *_port = (int)ntohs(_sockaddr.sin_port); } if (nullptr_t != _addr) { *_addr = inet_ntoa(_sockaddr.sin_addr); } } return ret_success; }
ret TcpConnection::send_raw_buffer(const byte* _buffer, int _size) { if_return(nullptr_t == _buffer || 0 >= _size, ret_fail); if_return(status_establish != this->connection_status_ || !tcp_server_, ret_fail); int _max_write_size = 0; if_return(!__success(this->tcp_server_->get_max_write_buffer(&_max_write_size)), ret_fail); if_return(_size + (int)this->write_buffer_.get_size() > _max_write_size, error_write_exceed); if (this->write_buffer_.get_size() <= 0) { int _write_size = ::write(this->fd_, _buffer, _size); if (_write_size < _size) { if (0 == _write_size || (_write_size == -1 && errno != EAGAIN)) { return this->on_set_close(this->fd_, this->poll_, false); } else { if (false == this->wait_for_write_ && this->poll_) { this->wait_for_write_ = __success(this->poll_ ->set_event_listener(fd_, event_write, event_callback_key_)); } if (-1 == _write_size) { this->write_buffer_.append_buffer(_buffer, _size); } else { this->write_buffer_.append_buffer(_buffer + _write_size, _size - _write_size); } } } else if (this->connection_status_ == status_closing) { this->on_set_close(this->fd_, this->poll_, true); } } else { this->write_buffer_.append_buffer(_buffer, _size); } return ret_success; }
ret TcpConnection::on_time(int id, IEventPoll* _poll) { if_return(!tcp_server_, ret_fail); int _timeout = 0; if_return(!__success(this->tcp_server_->get_timeout(&_timeout)), ret_fail); int64_t _interval_time = this->get_current_time() - this->last_read_time_; if (_interval_time >= _timeout) { return this->on_set_close(this->fd_, this->poll_, true); } else if (this->poll_) { this->poll_->add_timer_once(0, timer_callback_key_, _timeout - _interval_time); } return ret_fail; }
ret ThreadSwitch::commit(const Task* _task) { if_return(nullptr_t == _task, ret_args_error); ThreadTaskQueue::commit(_task); uint64_t _u = 1; ::write(this->event_fd_, &_u, sizeof(uint64_t)); return ret_success; }
ret UdpServer::wait_for_event(IEventPoll* _poll) { if_return(nullptr_t == _poll, ret_args_error); this->poll_ = _poll; this->poll_->set_event_listener(this->fd_, event_read, event_callback_key_); return ret_success; }
ret ThreadPool::do_task(Task* _task) { if_return(nullptr_t == _task, ret_args_error); if (nullptr_t == this->task_queue_) { _task->force_delete(); return ret_fail; } return this->task_queue_->commit(_task); }
__api ret __module_register(const common::IRegister* _reg) { if_return(_reg == nullptr_t, ret_args_error); __register(network::EventPoll, _reg); __register(network::TcpClient, _reg); __register(network::TcpServer, _reg); __register(network::TcpConnection, _reg); __register(network::HttpServer, _reg); __register(network::HttpConnection, _reg); return ret_success; }
ret ThreadPool::init(int _num) { if_return(0 >= _num, ret_args_error); this->task_queue_ = new(std::nothrow) ThreadPoolTaskQueue(); if_return(nullptr_t == this->task_queue_, ret_fail); this->task_queue_ ->add_ref(); for (int i = 0; i < _num; ++i) { pthread_t _t; pthread_attr_t _attr; ::pthread_attr_init(&_attr); ::pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_DETACHED); int _ret = ::pthread_create(&_t, &_attr, ThreadPool::__thread_function, (void*)task_queue_); ::pthread_attr_destroy(&_attr); if_continue(0 != _ret); } this->task_queue_ ->del_ref(); return ret_success; }
ret UdpServer::send_raw_buffer(const byte* _buffer, int _size, const sockaddr* _addr) { if_return(nullptr_t == _buffer || 0 >= _size, ret_fail); if (false == this->use_ipv6_) { ::sendto(this->fd_, _buffer, _size, 0, (sockaddr*)(&addr_struct_.addr_ipv4_struct_), sizeof(sockaddr_in)); } else { ::sendto(this->fd_, _buffer, _size, 0, (sockaddr*)(&addr_struct_.addr_ipv6_struct_), sizeof(sockaddr_in6)); } return ret_success; }
ret TcpConnection::close(bool _right_now) { if_return(this->connection_status_ & (status_establish | status_closing), ret_fail); if (_right_now || 0 >= this->write_buffer_.get_size()) { this->on_set_close(this->fd_, this->poll_, true); } else { this->connection_status_ = status_closing; } return ret_success; }
ret TcpConnection::follow_fd(int _fd, ITcpServer* _server) { if_return(_fd <= 0 || nullptr_t == _server, ret_args_error); this->fd_ = _fd; this->tcp_server_ = _server; if_return(!tcp_server_, ret_fail); int _opt_open_value = 1; setsockopt(this->fd_, IPPROTO_TCP, SO_REUSEADDR, (const void*)&_opt_open_value, sizeof(int)); setsockopt(this->fd_, IPPROTO_TCP, SO_KEEPALIVE, (const void*)&_opt_open_value, sizeof(int)); setsockopt(this->fd_, IPPROTO_TCP, TCP_NODELAY, (const void*)&_opt_open_value, sizeof(int)); fcntl(this->fd_, F_SETFL, fcntl(this->fd_, F_GETFL)|O_NONBLOCK); this->connection_status_ = status_establish; __sp<ITcpCallback> _callback; if (__success(this->tcp_server_->get_callback(&_callback)) && _callback) { _callback->on_connect(this->connection_self_, true); } return ret_success; }
ret UdpServer::listen_ipv6(const char* _addr, int _port, int _backlog) { if_return(0 != this->fd_, ret_fail); this->use_ipv6_ = true; if (this->fd_ = (int)socket(PF_INET6, SOCK_DGRAM, 0), fd_ <= 0) { perror("create socket"); this->fd_ = 0; return ret_fail; } memset(&addr_struct_.addr_ipv6_struct_, 0, sizeof(struct sockaddr_in6)); addr_struct_.addr_ipv6_struct_.sin6_family = AF_INET6; addr_struct_.addr_ipv6_struct_.sin6_port = htons(_port); if (nullptr_t == _addr) { addr_struct_.addr_ipv6_struct_.sin6_addr = in6addr_any;// IN6ADDR_ANY; } else { if_return(inet_pton(AF_INET6, _addr, &addr_struct_.addr_ipv6_struct_.sin6_addr) <= 0, ret_args_error); } int _opt_open_value = 1; setsockopt(this->fd_, SOL_SOCKET, SO_REUSEADDR, (const void*)&_opt_open_value, sizeof(int)); setsockopt(this->fd_, SOL_SOCKET, SO_KEEPALIVE, (const void*)&_opt_open_value, sizeof(int)); fcntl(this->fd_, F_SETFL, fcntl(this->fd_, F_GETFL)|O_NONBLOCK); if (::bind(this->fd_, (sockaddr*)(&addr_struct_.addr_ipv6_struct_), sizeof(sockaddr_in6)) == -1) { perror("bind error"); ::close(this->fd_); this->fd_ = 0; return ret_fail; } return ret_success; }
void* ThreadPool::__thread_function(void* _arg) { if_return(nullptr_t == _arg, 0); ThreadPoolTaskQueue* _task_queue = (ThreadPoolTaskQueue*) _arg; _task_queue->add_ref(); while (true) { int _left_task = 0; _task_queue->do_task(&_left_task); if_break(0 == _left_task); } _task_queue->del_ref(); _task_queue = nullptr_t; return 0; }
ret TcpConnection::wait_for_event(IEventPoll* _poll) { if_return(nullptr_t == _poll || !tcp_server_, ret_args_error); this->poll_ = _poll; if (this->fd_ > 0 && this->poll_) { this->poll_->set_event_listener(fd_, event_read, event_callback_key_); } int _timeout = 0; if (__success(this->tcp_server_->get_timeout(&_timeout)) && _timeout > 0) { this->set_time_out_ = true; this->poll_->add_timer_once(0, timer_callback_key_, _timeout); } return ret_success; }
ret UdpServer::on_read(int fd, IEventPoll* _poll) { const static int _max_read_buffer = 10240; byte _buffer[_max_read_buffer] = {0}; int _read_size = 0; socklen_t _addr_size = 0; if (false == this->use_ipv6_) { _read_size = ::recvfrom(this->fd_, _buffer, _max_read_buffer, 0, (sockaddr*)(&addr_struct_.addr_ipv4_struct_), &_addr_size); } else { _read_size = ::recvfrom(this->fd_, _buffer, _max_read_buffer, 0, (sockaddr*)(&addr_struct_.addr_ipv6_struct_), &_addr_size); } if_return(0 >= _read_size || !this->udp_callback_, ret_fail); this->udp_callback_->on_receive(this->udp_base_, _buffer, _read_size); return ret_success; }
ret TcpConnection::get_status(int* _status) { if_return(nullptr_t == _status, ret_args_error); *_status = this->connection_status_; return ret_success; }
ret UdpServer::use_ipv6(bool* _ipv6) { if_return(nullptr_t == _ipv6, ret_args_error); *_ipv6 = this->use_ipv6_; return ret_success; }
ret TcpConnection::get_delay_delete(bool* _delay) { if_return(nullptr_t == _delay, ret_args_error); *_delay = this->delay_delete_; return ret_success; }
ret UdpServer::send_buffer(const byte* _buffer, int _size, const sockaddr* _addr) { if_return(!this->protocol_, ret_fail); if_return(_buffer == nullptr_t || 0 >= _size, ret_args_error); return this->protocol_->encode(_buffer, _size, this->udp_base_, _addr); }
ret TcpConnection::on_read(int fd, IEventPoll* _poll) { const static int _max_read_buffer = 10240; byte _buffer[_max_read_buffer] = {0}; int _read_size = ::read(fd, _buffer, _max_read_buffer); if (0 == _read_size || (-1 == _read_size && EAGAIN != errno)) { this->on_set_close(fd, _poll, false); return callback_close; } if (_read_size > 0) { if_return(!tcp_server_, ret_fail); int _max_read_size = 0; if_return(!__success(this->tcp_server_->get_max_read_buffer(&_max_read_size)), ret_fail); __sp<ITcpProtocol> _protocol; if_return(!__success(this->tcp_server_->get_protocol(&_protocol)) || !_protocol, ret_fail); __sp<ITcpCallback> _callback; if_return(!__success(this->tcp_server_->get_callback(&_callback)) || !_callback, ret_fail); this->last_read_time_ = this->get_current_time(); if (_read_size + (int)this->read_buffer_.get_size() > _max_read_size) { this->on_set_close(fd, _poll, true); _callback->on_error(this->connection_self_, error_read_exceed); return callback_fail; } this->read_buffer_.append_buffer(_buffer, _read_size); while (true) { const byte* _buffer = nullptr_t; size_t _size = this->read_buffer_.get_buffer(&_buffer); if (-1 == this->want_read_buffer_size_) { int _want_size = -1; int _input_info = 0; _protocol->input(_buffer, (int)_size, &_want_size, &_input_info); if (tcp_protocol_error == _input_info) { this->on_set_close(fd, _poll, true); this->want_read_buffer_size_ = -1; _callback->on_error(this->connection_self_, error_input); return callback_fail; } else if (tcp_protocol_success == _input_info) { this->want_read_buffer_size_ = _want_size; } else if (tcp_protocol_not_enough == _input_info) { this->want_read_buffer_size_ = -1; } if_break(this->want_read_buffer_size_ <= 0); } if (this->want_read_buffer_size_ > 0) { if_break((int)this->read_buffer_.get_size() < this->want_read_buffer_size_); if (!__success(_protocol->decode(_buffer, want_read_buffer_size_, connection_self_))) { this->on_set_close(fd, _poll, true); _callback->on_error(this->connection_self_, error_decode); return callback_close; } this->read_buffer_.consume_buffer(this->want_read_buffer_size_); this->want_read_buffer_size_ = -1; if_break(0 >= this->read_buffer_.get_size()); } } return callback_continue; } return callback_complete; }
ret TcpConnection::on_write(int fd, IEventPoll* _poll) { #if 0 if_return(0 >= this->fd_ || nullptr_t == this->poll_, ret_fail); if_return(0 == this->write_buffer_.get_size(), callback_complete); const byte* _buffer = nullptr_t; int _size = 0; this->write_buffer_.get_first_block(&_buffer, &_size); int _write_size = ::write(fd, _buffer, _size); if (_write_size > 0) { this->write_buffer_.consume_first_block_size(_write_size); if_return(_write_size < _size, callback_complete); } else if (0 == _write_size || (-1 == _write_size && errno != EAGAIN)) { this->on_set_close(fd, _poll, false); return callback_close; } if (0 == this->write_buffer_.get_size()) { if (status_closing == this->connection_status_) { this->on_set_close(fd, _poll, true); return callback_close; } else { return callback_complete; } } return callback_continue; #endif//0 if_return(0 >= this->fd_ || nullptr_t == this->poll_, ret_fail); if_return(0 == this->write_buffer_.get_size(), callback_complete); const byte* _buffer = nullptr_t; int _size = 0; this->write_buffer_.get_first_block(&_buffer, &_size); int _write_size = ::write(fd, _buffer, _size); if (_write_size > 0) { this->write_buffer_.consume_first_block_size(_write_size); if (_write_size == _size) { if (0 == this->write_buffer_.get_size()) { if (status_closing == this->connection_status_) { this->on_set_close(fd, _poll, true); return callback_close; } return callback_complete; } return callback_continue; } return callback_complete; } else if (0 == _write_size || (-1 == _write_size && errno != EAGAIN)) { this->on_set_close(fd, _poll, false); return callback_close; } else if (-1 == _write_size) { return callback_again; } }
ret TcpConnection::use_ipv6(bool* _ipv6) { if_return(nullptr_t == _ipv6, ret_args_error); if_return(!tcp_server_, ret_fail); return this->tcp_server_->use_ipv6(_ipv6); }
/* * Return a CORBA-runtime-managed string that is equal to `name'; i.e., intern * the `name' and return the interned version. * * The returned string may be statically allocated; it may be returned many * times by different invocations of this function; it may not be modified or * freed by the caller. */ char * find_system_exception_id(char *name, int size) { static char **table = 0; static int count = 0, max = 0; int i; /* * If `name' matches a known CORBA system exception, return a * statically allocated string. */ #define if_return(exname) if(!strcmp(name, ex_##exname)) return ex_##exname if_return(CORBA_UNKNOWN); if_return(CORBA_BAD_PARAM); if_return(CORBA_NO_MEMORY); if_return(CORBA_IMP_LIMIT); if_return(CORBA_COMM_FAILURE); if_return(CORBA_INV_OBJREF); if_return(CORBA_NO_PERMISSION); if_return(CORBA_INTERNAL); if_return(CORBA_MARSHAL); if_return(CORBA_INITIALIZE); if_return(CORBA_NO_IMPLEMENT); if_return(CORBA_BAD_TYPECODE); if_return(CORBA_BAD_OPERATION); if_return(CORBA_NO_RESOURCES); if_return(CORBA_NO_RESPONSE); if_return(CORBA_PERSIST_STORE); if_return(CORBA_BAD_INV_ORDER); if_return(CORBA_TRANSIENT); if_return(CORBA_FREE_MEM); if_return(CORBA_INV_IDENT); if_return(CORBA_INV_FLAG); if_return(CORBA_INTF_REPOS); if_return(CORBA_BAD_CONTEXT); if_return(CORBA_OBJ_ADAPTER); if_return(CORBA_DATA_CONVERSION); if_return(CORBA_OBJECT_NOT_EXIST); if_return(CORBA_TRANSACTION_REQUIRED); if_return(CORBA_TRANSACTION_ROLLEDBACK); if_return(CORBA_INVALID_TRANSACTION); /* * Otherwise, we must search our table and possibly add a copy of * `name' to the table. */ for (i = 0; i < count; i++) if (!strcmp(table[i], name)) return table[i]; /* Add a copy of `name' to the table. */ if (count >= max) { int new_max = max + 10; char **new_table = t_realloc(table, char *, new_max); if (!new_table) { fprintf(stderr, "Error: can't allocate space for " "system exception identifier.\n"); /* XXX --- Is this a reasonable thing to do? */ return ex_CORBA_NO_MEMORY; } table = new_table; max = new_max; }
__api ret __module_factory(const _guid& _u, const _guid& _d, void** ppOut) { if_return(ppOut == nullptr_t, ret_args_error); return network::__module_register::create(_u, _d, ppOut) ? ret_success : ret_fail; }