예제 #1
0
    message_ex* dsn_message_parser::get_message_on_receive(int read_length, /*out*/ int& read_next)
    {
        mark_read(read_length);

        if (_read_buffer_occupied >= sizeof(message_header))
        {            
            int msg_sz = sizeof(message_header) +
                message_ex::get_body_length((char*)_read_buffer.data());

            // msg done
            if (_read_buffer_occupied >= msg_sz)
            {
                auto msg_bb = _read_buffer.range(0, msg_sz);
                message_ex* msg = message_ex::create_receive_message(msg_bb);

                dassert(msg->is_right_header() && msg->is_right_body(false), "");

                _read_buffer = _read_buffer.range(msg_sz);
                _read_buffer_occupied -= msg_sz;
                read_next = sizeof(message_header);
                return msg;
            }
            else
            {
                read_next = msg_sz - _read_buffer_occupied;
                return nullptr;
            }
        }

        else
        {
            read_next = sizeof(message_header) - _read_buffer_occupied;
            return nullptr;
        }
    }
예제 #2
0
void LogWriter::run()
{
	while (!_exit_thread) {
		// Outer endless loop
		// Wait for _should_run flag
		while (!_exit_thread) {
			bool start = false;
			pthread_mutex_lock(&_mtx);
			pthread_cond_wait(&_cv, &_mtx);
			start = _should_run;
			pthread_mutex_unlock(&_mtx);

			if (start) {
				break;
			}
		}

		int poll_count = 0;
		int written = 0;

		while (true) {
			size_t available = 0;
			void *read_ptr = nullptr;
			bool is_part = false;

			/* lock _buffer
			 * wait for sufficient data, cycle on notify()
			 */
			pthread_mutex_lock(&_mtx);

			while (true) {
				available = get_read_ptr(&read_ptr, &is_part);

				/* if sufficient data available or partial read or terminating, exit this wait loop */
				if ((available >= _min_write_chunk) || is_part || !_should_run) {
					/* GOTO end of block */
					break;
				}

				/* wait for a call to notify()
				 * this call unlocks the mutex while waiting, and returns with the mutex locked
				 */
				pthread_cond_wait(&_cv, &_mtx);
			}

			pthread_mutex_unlock(&_mtx);
			written = 0;

			if (available > 0) {
				perf_begin(_perf_write);
				written = ::write(_fd, read_ptr, available);
				perf_end(_perf_write);

				/* call fsync periodically to minimize potential loss of data */
				if (++poll_count >= 100) {
					perf_begin(_perf_fsync);
					::fsync(_fd);
					perf_end(_perf_fsync);
					poll_count = 0;
				}

				if (written < 0) {
					PX4_WARN("error writing log file");
					_should_run = false;
					/* GOTO end of block */
					break;
				}

				pthread_mutex_lock(&_mtx);
				/* subtract bytes written from number in _buffer (_count -= written) */
				mark_read(written);
				pthread_mutex_unlock(&_mtx);

				_total_written += written;
			}

			if (!_should_run && written == static_cast<int>(available) && !is_part) {
				// Stop only when all data written
				_running = false;
				_head = 0;
				_count = 0;

				if (_fd >= 0) {
					int res = ::close(_fd);
					_fd = -1;

					if (res) {
						PX4_WARN("error closing log file");

					} else {
						PX4_INFO("closed logfile: %s, bytes written: %zu", _filename, _total_written);
					}
				}

				break;
			}
		}
	}
}
예제 #3
0
    message_ex* dsn_message_parser::get_message_on_receive(int read_length, /*out*/ int& read_next)
    {
        mark_read(read_length);

        if (_read_buffer_occupied >= sizeof(message_header))
        {
            if (!_header_checked)
            {
                if (!message_ex::is_right_header((char*)_read_buffer.data()))
                {
                    derror("receive message header check failed for message");

                    truncate_read();
                    read_next = -1;
                    return nullptr;
                }
                else
                {
                    _header_checked = true;
                }
            }

            int msg_sz = sizeof(message_header) +
                message_ex::get_body_length((char*)_read_buffer.data());

            // msg done
            if (_read_buffer_occupied >= msg_sz)
            {
                auto msg_bb = _read_buffer.range(0, msg_sz);
                message_ex* msg = message_ex::create_receive_message(msg_bb);
                if (!msg->is_right_body(false))
                {
                    message_header* header = (message_header*)_read_buffer.data();
                    derror("body check failed for message, id: %d, rpc_name: %s, from: %s",
                          header->id, header->rpc_name, header->from_address.to_string());

                    truncate_read();
                    read_next = -1;
                    return nullptr;
                }
                else
                {
                    _read_buffer = _read_buffer.range(msg_sz);
                    _read_buffer_occupied -= msg_sz;
                    _header_checked = false;

                    read_next = sizeof(message_header);
                    return msg;
                }
            }
            else
            {
                read_next = msg_sz - _read_buffer_occupied;
                return nullptr;
            }
        }

        else
        {
            read_next = sizeof(message_header) - _read_buffer_occupied;
            return nullptr;
        }
    }