1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 113c5fc84109e806cd97be2ce6cd720e1cc949f26dphoglund@webrtc.org#include "webrtc/system_wrappers/interface/data_log.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <assert.h> 14c6d6fed3c0a82bb7a09095381b974e8e5eebcb35pbos@webrtc.org 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <algorithm> 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <list> 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 183c5fc84109e806cd97be2ce6cd720e1cc949f26dphoglund@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 193c5fc84109e806cd97be2ce6cd720e1cc949f26dphoglund@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h" 203c5fc84109e806cd97be2ce6cd720e1cc949f26dphoglund@webrtc.org#include "webrtc/system_wrappers/interface/file_wrapper.h" 213c5fc84109e806cd97be2ce6cd720e1cc949f26dphoglund@webrtc.org#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h" 223c5fc84109e806cd97be2ce6cd720e1cc949f26dphoglund@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h" 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgDataLogImpl::CritSectScopedPtr DataLogImpl::crit_sect_( 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionWrapper::CreateCriticalSection()); 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgDataLogImpl* DataLogImpl::instance_ = NULL; 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// A Row contains cells, which are indexed by the column names as std::string. 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// The string index is treated in a case sensitive way. 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass Row { 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Row(); 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ~Row(); 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Inserts a Container into the cell of the column specified with 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // column_name. 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // column_name is treated in a case sensitive way. 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int InsertCell(const std::string& column_name, 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Container* value_container); 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Converts the value at the column specified by column_name to a string 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // stored in value_string. 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // column_name is treated in a case sensitive way. 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void ToString(const std::string& column_name, std::string* value_string); 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private: 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Collection of containers indexed by column name as std::string 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef std::map<std::string, const Container*> CellMap; 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CellMap cells_; 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionWrapper* cells_lock_; 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// A LogTable contains multiple rows, where only the latest row is active for 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// editing. The rows are defined by the ColumnMap, which contains the name of 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// each column and the length of the column (1 for one-value-columns and greater 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// than 1 for multi-value-columns). 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass LogTable { 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LogTable(); 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ~LogTable(); 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Adds the column with name column_name to the table. The column will be a 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // multi-value-column if multi_value_length is greater than 1. 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // column_name is treated in a case sensitive way. 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int AddColumn(const std::string& column_name, int multi_value_length); 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Buffers the current row while it is waiting to be written to file, 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // which is done by a call to Flush(). A new row is available when the 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // function returns 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void NextRow(); 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Inserts a Container into the cell of the column specified with 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // column_name. 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // column_name is treated in a case sensitive way. 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int InsertCell(const std::string& column_name, 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Container* value_container); 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Creates a log file, named as specified in the string file_name, to 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // where the table will be written when calling Flush(). 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int CreateLogFile(const std::string& file_name); 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Write all complete rows to file. 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // May not be called by two threads simultaneously (doing so may result in 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // a race condition). Will be called by the file_writer_thread_ when that 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // thread is running. 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void Flush(); 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private: 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Collection of multi_value_lengths indexed by column name as std::string 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef std::map<std::string, int> ColumnMap; 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org typedef std::list<Row*> RowList; 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ColumnMap columns_; 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RowList rows_[2]; 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RowList* rows_history_; 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RowList* rows_flush_; 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Row* current_row_; 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FileWrapper* file_; 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool write_header_; 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionWrapper* table_lock_; 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRow::Row() 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : cells_(), 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cells_lock_(CriticalSectionWrapper::CreateCriticalSection()) { 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRow::~Row() { 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (CellMap::iterator it = cells_.begin(); it != cells_.end();) { 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete it->second; 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // For maps all iterators (except the erased) are valid after an erase 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cells_.erase(it++); 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete cells_lock_; 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint Row::InsertCell(const std::string& column_name, 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Container* value_container) { 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped synchronize(cells_lock_); 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(cells_.count(column_name) == 0); 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (cells_.count(column_name) > 0) 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org cells_[column_name] = value_container; 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid Row::ToString(const std::string& column_name, 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::string* value_string) { 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped synchronize(cells_lock_); 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Container* container = cells_[column_name]; 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (container == NULL) { 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *value_string = "NaN,"; 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org container->ToString(value_string); 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgLogTable::LogTable() 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : columns_(), 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rows_(), 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rows_history_(&rows_[0]), 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rows_flush_(&rows_[1]), 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org current_row_(new Row), 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_(FileWrapper::Create()), 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org write_header_(true), 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org table_lock_(CriticalSectionWrapper::CreateCriticalSection()) { 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgLogTable::~LogTable() { 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (RowList::iterator row_it = rows_history_->begin(); 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org row_it != rows_history_->end();) { 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete *row_it; 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org row_it = rows_history_->erase(row_it); 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (ColumnMap::iterator col_it = columns_.begin(); 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org col_it != columns_.end();) { 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // For maps all iterators (except the erased) are valid after an erase 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org columns_.erase(col_it++); 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (file_ != NULL) { 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_->Flush(); 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_->CloseFile(); 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete file_; 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete current_row_; 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete table_lock_; 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint LogTable::AddColumn(const std::string& column_name, 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int multi_value_length) { 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(multi_value_length > 0); 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!write_header_) { 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // It's not allowed to add new columns after the header 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // has been written. 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(false); 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped synchronize(table_lock_); 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (write_header_) 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org columns_[column_name] = multi_value_length; 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid LogTable::NextRow() { 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped sync_rows(table_lock_); 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rows_history_->push_back(current_row_); 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org current_row_ = new Row; 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint LogTable::InsertCell(const std::string& column_name, 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Container* value_container) { 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped synchronize(table_lock_); 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(columns_.count(column_name) > 0); 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (columns_.count(column_name) == 0) 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return current_row_->InsertCell(column_name, value_container); 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint LogTable::CreateLogFile(const std::string& file_name) { 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (file_name.length() == 0) 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (file_->Open()) 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_->OpenFile(file_name.c_str(), 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org false, // Open with read/write permissions 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org false, // Don't wraparound and write at the beginning when 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // the file is full 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org true); // Open as a text file 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (file_ == NULL) 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid LogTable::Flush() { 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ColumnMap::iterator column_it; 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool commit_header = false; 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (write_header_) { 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped synchronize(table_lock_); 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (write_header_) { 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org commit_header = true; 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org write_header_ = false; 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (commit_header) { 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (column_it = columns_.begin(); 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org column_it != columns_.end(); ++column_it) { 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (column_it->second > 1) { 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_->WriteText("%s[%u],", column_it->first.c_str(), 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org column_it->second); 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 1; i < column_it->second; ++i) 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_->WriteText(","); 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_->WriteText("%s,", column_it->first.c_str()); 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (columns_.size() > 0) 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_->WriteText("\n"); 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Swap the list used for flushing with the list containing the row history 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // and clear the history. We also create a local pointer to the new 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // list used for flushing to avoid race conditions if another thread 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // calls this function while we are writing. 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We don't want to block the list while we're writing to file. 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped synchronize(table_lock_); 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RowList* tmp = rows_flush_; 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rows_flush_ = rows_history_; 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rows_history_ = tmp; 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rows_history_->clear(); 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Write all complete rows to file and delete them 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (RowList::iterator row_it = rows_flush_->begin(); 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org row_it != rows_flush_->end();) { 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (column_it = columns_.begin(); 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org column_it != columns_.end(); ++column_it) { 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::string row_string; 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*row_it)->ToString(column_it->first, &row_string); 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_->WriteText("%s", row_string.c_str()); 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (columns_.size() > 0) 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_->WriteText("\n"); 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete *row_it; 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org row_it = rows_flush_->erase(row_it); 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLog::CreateLog() { 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return DataLogImpl::CreateLog(); 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid DataLog::ReturnLog() { 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return DataLogImpl::ReturnLog(); 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstd::string DataLog::Combine(const std::string& table_name, int table_id) { 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::stringstream ss; 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::string combined_id = table_name; 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::string number_suffix; 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ss << "_" << table_id; 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ss >> number_suffix; 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org combined_id += number_suffix; 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::transform(combined_id.begin(), combined_id.end(), combined_id.begin(), 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ::tolower); 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return combined_id; 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLog::AddTable(const std::string& table_name) { 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DataLogImpl* data_log = DataLogImpl::StaticInstance(); 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (data_log == NULL) 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return data_log->AddTable(table_name); 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLog::AddColumn(const std::string& table_name, 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const std::string& column_name, 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int multi_value_length) { 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DataLogImpl* data_log = DataLogImpl::StaticInstance(); 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (data_log == NULL) 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return data_log->DataLogImpl::StaticInstance()->AddColumn(table_name, 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org column_name, 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org multi_value_length); 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLog::NextRow(const std::string& table_name) { 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DataLogImpl* data_log = DataLogImpl::StaticInstance(); 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (data_log == NULL) 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return data_log->DataLogImpl::StaticInstance()->NextRow(table_name); 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgDataLogImpl::DataLogImpl() 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : counter_(1), 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tables_(), 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org flush_event_(EventWrapper::Create()), 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_writer_thread_(NULL), 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tables_lock_(RWLockWrapper::CreateRWLock()) { 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgDataLogImpl::~DataLogImpl() { 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StopThread(); 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Flush(); // Write any remaining rows 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete file_writer_thread_; 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete flush_event_; 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (TableMap::iterator it = tables_.begin(); it != tables_.end();) { 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete static_cast<LogTable*>(it->second); 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // For maps all iterators (except the erased) are valid after an erase 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tables_.erase(it++); 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete tables_lock_; 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLogImpl::CreateLog() { 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped synchronize(crit_sect_.get()); 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instance_ == NULL) { 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instance_ = new DataLogImpl(); 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return instance_->Init(); 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ++instance_->counter_; 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLogImpl::Init() { 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_writer_thread_ = ThreadWrapper::CreateThread( 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DataLogImpl::Run, 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instance_, 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kHighestPriority, 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "DataLog"); 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (file_writer_thread_ == NULL) 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned int thread_id = 0; 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool success = file_writer_thread_->Start(thread_id); 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!success) 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgDataLogImpl* DataLogImpl::StaticInstance() { 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return instance_; 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid DataLogImpl::ReturnLog() { 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped synchronize(crit_sect_.get()); 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instance_ && instance_->counter_ > 1) { 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org --instance_->counter_; 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete instance_; 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instance_ = NULL; 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLogImpl::AddTable(const std::string& table_name) { 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WriteLockScoped synchronize(*tables_lock_); 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Make sure we don't add a table which already exists 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (tables_.count(table_name) > 0) 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tables_[table_name] = new LogTable(); 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (tables_[table_name]->CreateLogFile(table_name + ".txt") == -1) 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLogImpl::AddColumn(const std::string& table_name, 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const std::string& column_name, 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int multi_value_length) { 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ReadLockScoped synchronize(*tables_lock_); 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (tables_.count(table_name) == 0) 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return tables_[table_name]->AddColumn(column_name, multi_value_length); 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLogImpl::InsertCell(const std::string& table_name, 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const std::string& column_name, 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Container* value_container) { 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ReadLockScoped synchronize(*tables_lock_); 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(tables_.count(table_name) > 0); 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (tables_.count(table_name) == 0) 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return tables_[table_name]->InsertCell(column_name, value_container); 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint DataLogImpl::NextRow(const std::string& table_name) { 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ReadLockScoped synchronize(*tables_lock_); 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (tables_.count(table_name) == 0) 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tables_[table_name]->NextRow(); 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (file_writer_thread_ == NULL) { 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Write every row to file as they get complete. 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tables_[table_name]->Flush(); 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Signal a complete row 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org flush_event_->Set(); 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid DataLogImpl::Flush() { 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ReadLockScoped synchronize(*tables_lock_); 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (TableMap::iterator it = tables_.begin(); it != tables_.end(); ++it) { 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org it->second->Flush(); 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool DataLogImpl::Run(void* obj) { 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<DataLogImpl*>(obj)->Process(); 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid DataLogImpl::Process() { 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Wait for a row to be complete 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org flush_event_->Wait(WEBRTC_EVENT_INFINITE); 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Flush(); 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid DataLogImpl::StopThread() { 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (file_writer_thread_ != NULL) { 447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org file_writer_thread_->SetNotAlive(); 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org flush_event_->Set(); 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Call Stop() repeatedly, waiting for the Flush() call in Process() to 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // finish. 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (!file_writer_thread_->Stop()) continue; 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 456