Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Side by Side Diff: third_party/leveldatabase/env_chromium.cc

Issue 11776009: Log IDB leveldb uma stats into LevelDBEnv.IDB. Other LevelDB consumers will (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix >80, make method definitions not inline Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/leveldatabase/README.chromium ('k') | third_party/leveldatabase/env_idb.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors. 3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 4
5 #include <deque> 5 #include <deque>
6 #include <errno.h> 6 #include <errno.h>
7 #include <stdio.h> 7 #include <stdio.h>
8 #include "base/at_exit.h" 8 #include "base/at_exit.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 kDeleteDir, 117 kDeleteDir,
118 kGetFileSize, 118 kGetFileSize,
119 kRenamefile, 119 kRenamefile,
120 kLockFile, 120 kLockFile,
121 kUnlockFile, 121 kUnlockFile,
122 kGetTestDirectory, 122 kGetTestDirectory,
123 kNewLogger, 123 kNewLogger,
124 kNumEntries 124 kNumEntries
125 }; 125 };
126 126
127 void LogToUMA(UmaEntry entry) { 127 class UMALogger {
128 UMA_HISTOGRAM_ENUMERATION("LevelDBEnv.IOError", entry, kNumEntries); 128 public:
129 UMALogger(std::string uma_title);
130 void RecordErrorAt(UmaEntry entry) const;
131 void LogRandomAccessFileError(base::PlatformFileError error_code) const;
132
133 private:
134 std::string uma_title_;
135 };
136
137 UMALogger::UMALogger(std::string uma_title) : uma_title_(uma_title) {}
138
139 void UMALogger::RecordErrorAt(UmaEntry entry) const {
140 std::string uma_name(uma_title_);
141 uma_name.append(".IOError");
142 UMA_HISTOGRAM_ENUMERATION(uma_name, entry, kNumEntries);
129 } 143 }
130 144
131 void LogRandomAccessFileError(base::PlatformFileError error_code) { 145 void UMALogger::LogRandomAccessFileError(base::PlatformFileError error_code)
146 const {
132 DCHECK(error_code < 0); 147 DCHECK(error_code < 0);
133 UMA_HISTOGRAM_ENUMERATION("LevelDBEnv.IOError.RandomAccessFile", 148 std::string uma_name(uma_title_);
149 uma_name.append(".IOError.RandomAccessFile");
150 UMA_HISTOGRAM_ENUMERATION(uma_name,
134 -error_code, 151 -error_code,
135 -base::PLATFORM_FILE_ERROR_MAX); 152 -base::PLATFORM_FILE_ERROR_MAX);
136 } 153 }
137 154
138 } // namespace 155 } // namespace
139 156
140 namespace leveldb { 157 namespace leveldb {
141 158
142 namespace { 159 namespace {
143 160
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 NOTREACHED(); 201 NOTREACHED();
185 } 202 }
186 NOTIMPLEMENTED(); 203 NOTIMPLEMENTED();
187 return "Unknown error."; 204 return "Unknown error.";
188 } 205 }
189 206
190 class ChromiumSequentialFile: public SequentialFile { 207 class ChromiumSequentialFile: public SequentialFile {
191 private: 208 private:
192 std::string filename_; 209 std::string filename_;
193 FILE* file_; 210 FILE* file_;
211 const UMALogger* uma_logger_;
194 212
195 public: 213 public:
196 ChromiumSequentialFile(const std::string& fname, FILE* f) 214 ChromiumSequentialFile(const std::string& fname, FILE* f,
197 : filename_(fname), file_(f) { } 215 const UMALogger* uma_logger)
216 : filename_(fname), file_(f), uma_logger_(uma_logger) { }
198 virtual ~ChromiumSequentialFile() { fclose(file_); } 217 virtual ~ChromiumSequentialFile() { fclose(file_); }
199 218
200 virtual Status Read(size_t n, Slice* result, char* scratch) { 219 virtual Status Read(size_t n, Slice* result, char* scratch) {
201 Status s; 220 Status s;
202 size_t r = fread_unlocked(scratch, 1, n, file_); 221 size_t r = fread_unlocked(scratch, 1, n, file_);
203 *result = Slice(scratch, r); 222 *result = Slice(scratch, r);
204 if (r < n) { 223 if (r < n) {
205 if (feof(file_)) { 224 if (feof(file_)) {
206 // We leave status as ok if we hit the end of the file 225 // We leave status as ok if we hit the end of the file
207 } else { 226 } else {
208 // A partial read with an error: return a non-ok status 227 // A partial read with an error: return a non-ok status
209 s = Status::IOError(filename_, strerror(errno)); 228 s = Status::IOError(filename_, strerror(errno));
210 LogToUMA(kSequentialFileRead); 229 uma_logger_->RecordErrorAt(kSequentialFileRead);
211 } 230 }
212 } 231 }
213 return s; 232 return s;
214 } 233 }
215 234
216 virtual Status Skip(uint64_t n) { 235 virtual Status Skip(uint64_t n) {
217 if (fseek(file_, n, SEEK_CUR)) { 236 if (fseek(file_, n, SEEK_CUR)) {
218 LogToUMA(kSequentialFileSkip); 237 uma_logger_->RecordErrorAt(kSequentialFileSkip);
219 return Status::IOError(filename_, strerror(errno)); 238 return Status::IOError(filename_, strerror(errno));
220 } 239 }
221 return Status::OK(); 240 return Status::OK();
222 } 241 }
223 }; 242 };
224 243
225 class ChromiumRandomAccessFile: public RandomAccessFile { 244 class ChromiumRandomAccessFile: public RandomAccessFile {
226 private: 245 private:
227 std::string filename_; 246 std::string filename_;
228 ::base::PlatformFile file_; 247 ::base::PlatformFile file_;
248 const UMALogger* uma_logger_;
229 249
230 public: 250 public:
231 ChromiumRandomAccessFile(const std::string& fname, ::base::PlatformFile file) 251 ChromiumRandomAccessFile(const std::string& fname, ::base::PlatformFile file,
232 : filename_(fname), file_(file) { } 252 const UMALogger* uma_logger)
253 : filename_(fname), file_(file), uma_logger_(uma_logger) { }
233 virtual ~ChromiumRandomAccessFile() { ::base::ClosePlatformFile(file_); } 254 virtual ~ChromiumRandomAccessFile() { ::base::ClosePlatformFile(file_); }
234 255
235 virtual Status Read(uint64_t offset, size_t n, Slice* result, 256 virtual Status Read(uint64_t offset, size_t n, Slice* result,
236 char* scratch) const { 257 char* scratch) const {
237 Status s; 258 Status s;
238 int r = ::base::ReadPlatformFile(file_, offset, scratch, n); 259 int r = ::base::ReadPlatformFile(file_, offset, scratch, n);
239 *result = Slice(scratch, (r < 0) ? 0 : r); 260 *result = Slice(scratch, (r < 0) ? 0 : r);
240 if (r < 0) { 261 if (r < 0) {
241 // An error: return a non-ok status 262 // An error: return a non-ok status
242 s = Status::IOError(filename_, "Could not perform read"); 263 s = Status::IOError(filename_, "Could not perform read");
243 LogToUMA(kRandomAccessFileRead); 264 uma_logger_->RecordErrorAt(kRandomAccessFileRead);
244 } 265 }
245 return s; 266 return s;
246 } 267 }
247 }; 268 };
248 269
249 class ChromiumWritableFile : public WritableFile { 270 class ChromiumWritableFile : public WritableFile {
250 private: 271 private:
251 std::string filename_; 272 std::string filename_;
252 FILE* file_; 273 FILE* file_;
274 const UMALogger* uma_logger_;
253 275
254 public: 276 public:
255 ChromiumWritableFile(const std::string& fname, FILE* f) 277 ChromiumWritableFile(const std::string& fname, FILE* f,
256 : filename_(fname), file_(f) { } 278 const UMALogger* uma_logger)
279 : filename_(fname), file_(f), uma_logger_(uma_logger) { }
257 280
258 ~ChromiumWritableFile() { 281 ~ChromiumWritableFile() {
259 if (file_ != NULL) { 282 if (file_ != NULL) {
260 // Ignoring any potential errors 283 // Ignoring any potential errors
261 fclose(file_); 284 fclose(file_);
262 } 285 }
263 } 286 }
264 287
265 virtual Status Append(const Slice& data) { 288 virtual Status Append(const Slice& data) {
266 size_t r = fwrite_unlocked(data.data(), 1, data.size(), file_); 289 size_t r = fwrite_unlocked(data.data(), 1, data.size(), file_);
267 Status result; 290 Status result;
268 if (r != data.size()) { 291 if (r != data.size()) {
269 result = Status::IOError(filename_, strerror(errno)); 292 result = Status::IOError(filename_, strerror(errno));
270 LogToUMA(kWritableFileAppend); 293 uma_logger_->RecordErrorAt(kWritableFileAppend);
271 } 294 }
272 return result; 295 return result;
273 } 296 }
274 297
275 virtual Status Close() { 298 virtual Status Close() {
276 Status result; 299 Status result;
277 if (fclose(file_) != 0) { 300 if (fclose(file_) != 0) {
278 result = Status::IOError(filename_, strerror(errno)); 301 result = Status::IOError(filename_, strerror(errno));
279 LogToUMA(kWritableFileClose); 302 uma_logger_->RecordErrorAt(kWritableFileClose);
280 } 303 }
281 file_ = NULL; 304 file_ = NULL;
282 return result; 305 return result;
283 } 306 }
284 307
285 virtual Status Flush() { 308 virtual Status Flush() {
286 Status result; 309 Status result;
287 if (fflush_unlocked(file_) != 0) { 310 if (fflush_unlocked(file_) != 0) {
288 result = Status::IOError(filename_, strerror(errno)); 311 result = Status::IOError(filename_, strerror(errno));
289 LogToUMA(kWritableFileFlush); 312 uma_logger_->RecordErrorAt(kWritableFileFlush);
290 } 313 }
291 return result; 314 return result;
292 } 315 }
293 316
294 virtual Status Sync() { 317 virtual Status Sync() {
295 Status result; 318 Status result;
296 int error = 0; 319 int error = 0;
297 320
298 if (fflush_unlocked(file_)) 321 if (fflush_unlocked(file_))
299 error = errno; 322 error = errno;
300 // Sync even if fflush gave an error; perhaps the data actually got out, 323 // Sync even if fflush gave an error; perhaps the data actually got out,
301 // even though something went wrong. 324 // even though something went wrong.
302 if (fdatasync(fileno(file_)) && !error) 325 if (fdatasync(fileno(file_)) && !error)
303 error = errno; 326 error = errno;
304 // Report the first error we found. 327 // Report the first error we found.
305 if (error) { 328 if (error) {
306 result = Status::IOError(filename_, strerror(error)); 329 result = Status::IOError(filename_, strerror(error));
307 LogToUMA(kWritableFileSync); 330 uma_logger_->RecordErrorAt(kWritableFileSync);
308 } 331 }
309 return result; 332 return result;
310 } 333 }
311 }; 334 };
312 335
313 class ChromiumFileLock : public FileLock { 336 class ChromiumFileLock : public FileLock {
314 public: 337 public:
315 ::base::PlatformFile file_; 338 ::base::PlatformFile file_;
316 }; 339 };
317 340
318 class ChromiumEnv : public Env { 341 class ChromiumEnv : public Env {
319 public: 342 public:
320 ChromiumEnv(); 343 ChromiumEnv();
321 virtual ~ChromiumEnv() { 344 virtual ~ChromiumEnv() {
322 NOTREACHED(); 345 NOTREACHED();
323 } 346 }
324 347
325 virtual Status NewSequentialFile(const std::string& fname, 348 virtual Status NewSequentialFile(const std::string& fname,
326 SequentialFile** result) { 349 SequentialFile** result) {
327 FILE* f = fopen_internal(fname.c_str(), "rb"); 350 FILE* f = fopen_internal(fname.c_str(), "rb");
328 if (f == NULL) { 351 if (f == NULL) {
329 *result = NULL; 352 *result = NULL;
330 LogToUMA(kNewSequentialFile); 353 uma_logger_->RecordErrorAt(kNewSequentialFile);
331 return Status::IOError(fname, strerror(errno)); 354 return Status::IOError(fname, strerror(errno));
332 } else { 355 } else {
333 *result = new ChromiumSequentialFile(fname, f); 356 *result = new ChromiumSequentialFile(fname, f, uma_logger_.get());
334 return Status::OK(); 357 return Status::OK();
335 } 358 }
336 } 359 }
337 360
338 virtual Status NewRandomAccessFile(const std::string& fname, 361 virtual Status NewRandomAccessFile(const std::string& fname,
339 RandomAccessFile** result) { 362 RandomAccessFile** result) {
340 int flags = ::base::PLATFORM_FILE_READ | ::base::PLATFORM_FILE_OPEN; 363 int flags = ::base::PLATFORM_FILE_READ | ::base::PLATFORM_FILE_OPEN;
341 bool created; 364 bool created;
342 ::base::PlatformFileError error_code; 365 ::base::PlatformFileError error_code;
343 ::base::PlatformFile file = ::base::CreatePlatformFile( 366 ::base::PlatformFile file = ::base::CreatePlatformFile(
344 CreateFilePath(fname), flags, &created, &error_code); 367 CreateFilePath(fname), flags, &created, &error_code);
345 if (error_code != ::base::PLATFORM_FILE_OK) { 368 if (error_code != ::base::PLATFORM_FILE_OK) {
346 *result = NULL; 369 *result = NULL;
347 LogToUMA(kNewRandomAccessFile); 370 uma_logger_->RecordErrorAt(kNewRandomAccessFile);
348 LogRandomAccessFileError(error_code); 371 uma_logger_->LogRandomAccessFileError(error_code);
349 return Status::IOError(fname, PlatformFileErrorString(error_code)); 372 return Status::IOError(fname, PlatformFileErrorString(error_code));
350 } 373 }
351 *result = new ChromiumRandomAccessFile(fname, file); 374 *result = new ChromiumRandomAccessFile(fname, file, uma_logger_.get());
352 return Status::OK(); 375 return Status::OK();
353 } 376 }
354 377
355 virtual Status NewWritableFile(const std::string& fname, 378 virtual Status NewWritableFile(const std::string& fname,
356 WritableFile** result) { 379 WritableFile** result) {
357 *result = NULL; 380 *result = NULL;
358 FILE* f = fopen_internal(fname.c_str(), "wb"); 381 FILE* f = fopen_internal(fname.c_str(), "wb");
359 if (f == NULL) { 382 if (f == NULL) {
360 LogToUMA(kNewWritableFile); 383 uma_logger_->RecordErrorAt(kNewWritableFile);
361 return Status::IOError(fname, strerror(errno)); 384 return Status::IOError(fname, strerror(errno));
362 } else { 385 } else {
363 if (!sync_parent(fname)) { 386 if (!sync_parent(fname)) {
364 fclose(f); 387 fclose(f);
365 return Status::IOError(fname, strerror(errno)); 388 return Status::IOError(fname, strerror(errno));
366 } 389 }
367 *result = new ChromiumWritableFile(fname, f); 390 *result = new ChromiumWritableFile(fname, f, uma_logger_.get());
368 return Status::OK(); 391 return Status::OK();
369 } 392 }
370 } 393 }
371 394
372 virtual bool FileExists(const std::string& fname) { 395 virtual bool FileExists(const std::string& fname) {
373 return ::file_util::PathExists(CreateFilePath(fname)); 396 return ::file_util::PathExists(CreateFilePath(fname));
374 } 397 }
375 398
376 virtual Status GetChildren(const std::string& dir, 399 virtual Status GetChildren(const std::string& dir,
377 std::vector<std::string>* result) { 400 std::vector<std::string>* result) {
378 result->clear(); 401 result->clear();
379 ::file_util::FileEnumerator iter( 402 ::file_util::FileEnumerator iter(
380 CreateFilePath(dir), false, ::file_util::FileEnumerator::FILES); 403 CreateFilePath(dir), false, ::file_util::FileEnumerator::FILES);
381 ::FilePath current = iter.Next(); 404 ::FilePath current = iter.Next();
382 while (!current.empty()) { 405 while (!current.empty()) {
383 result->push_back(FilePathToString(current.BaseName())); 406 result->push_back(FilePathToString(current.BaseName()));
384 current = iter.Next(); 407 current = iter.Next();
385 } 408 }
386 // TODO(jorlow): Unfortunately, the FileEnumerator swallows errors, so 409 // TODO(jorlow): Unfortunately, the FileEnumerator swallows errors, so
387 // we'll always return OK. Maybe manually check for error 410 // we'll always return OK. Maybe manually check for error
388 // conditions like the file not existing? 411 // conditions like the file not existing?
389 return Status::OK(); 412 return Status::OK();
390 } 413 }
391 414
392 virtual Status DeleteFile(const std::string& fname) { 415 virtual Status DeleteFile(const std::string& fname) {
393 Status result; 416 Status result;
394 // TODO(jorlow): Should we assert this is a file? 417 // TODO(jorlow): Should we assert this is a file?
395 if (!::file_util::Delete(CreateFilePath(fname), false)) { 418 if (!::file_util::Delete(CreateFilePath(fname), false)) {
396 result = Status::IOError(fname, "Could not delete file."); 419 result = Status::IOError(fname, "Could not delete file.");
397 LogToUMA(kDeleteFile); 420 uma_logger_->RecordErrorAt(kDeleteFile);
398 } 421 }
399 return result; 422 return result;
400 }; 423 };
401 424
402 virtual Status CreateDir(const std::string& name) { 425 virtual Status CreateDir(const std::string& name) {
403 Status result; 426 Status result;
404 if (!::file_util::CreateDirectory(CreateFilePath(name))) { 427 if (!::file_util::CreateDirectory(CreateFilePath(name))) {
405 result = Status::IOError(name, "Could not create directory."); 428 result = Status::IOError(name, "Could not create directory.");
406 LogToUMA(kCreateDir); 429 uma_logger_->RecordErrorAt(kCreateDir);
407 } 430 }
408 return result; 431 return result;
409 }; 432 };
410 433
411 virtual Status DeleteDir(const std::string& name) { 434 virtual Status DeleteDir(const std::string& name) {
412 Status result; 435 Status result;
413 // TODO(jorlow): Should we assert this is a directory? 436 // TODO(jorlow): Should we assert this is a directory?
414 if (!::file_util::Delete(CreateFilePath(name), false)) { 437 if (!::file_util::Delete(CreateFilePath(name), false)) {
415 result = Status::IOError(name, "Could not delete directory."); 438 result = Status::IOError(name, "Could not delete directory.");
416 LogToUMA(kDeleteDir); 439 uma_logger_->RecordErrorAt(kDeleteDir);
417 } 440 }
418 return result; 441 return result;
419 }; 442 };
420 443
421 virtual Status GetFileSize(const std::string& fname, uint64_t* size) { 444 virtual Status GetFileSize(const std::string& fname, uint64_t* size) {
422 Status s; 445 Status s;
423 int64_t signed_size; 446 int64_t signed_size;
424 if (!::file_util::GetFileSize(CreateFilePath(fname), &signed_size)) { 447 if (!::file_util::GetFileSize(CreateFilePath(fname), &signed_size)) {
425 *size = 0; 448 *size = 0;
426 s = Status::IOError(fname, "Could not determine file size."); 449 s = Status::IOError(fname, "Could not determine file size.");
427 LogToUMA(kGetFileSize); 450 uma_logger_->RecordErrorAt(kGetFileSize);
428 } else { 451 } else {
429 *size = static_cast<uint64_t>(signed_size); 452 *size = static_cast<uint64_t>(signed_size);
430 } 453 }
431 return s; 454 return s;
432 } 455 }
433 456
434 virtual Status RenameFile(const std::string& src, const std::string& dst) { 457 virtual Status RenameFile(const std::string& src, const std::string& dst) {
435 Status result; 458 Status result;
436 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) { 459 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) {
437 result = Status::IOError(src, "Could not rename file."); 460 result = Status::IOError(src, "Could not rename file.");
438 LogToUMA(kRenamefile); 461 uma_logger_->RecordErrorAt(kRenamefile);
439 } else { 462 } else {
440 sync_parent(dst); 463 sync_parent(dst);
441 if (src != dst) 464 if (src != dst)
442 sync_parent(src); 465 sync_parent(src);
443 } 466 }
444 return result; 467 return result;
445 } 468 }
446 469
447 virtual Status LockFile(const std::string& fname, FileLock** lock) { 470 virtual Status LockFile(const std::string& fname, FileLock** lock) {
448 *lock = NULL; 471 *lock = NULL;
449 Status result; 472 Status result;
450 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS | 473 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS |
451 ::base::PLATFORM_FILE_READ | 474 ::base::PLATFORM_FILE_READ |
452 ::base::PLATFORM_FILE_WRITE | 475 ::base::PLATFORM_FILE_WRITE |
453 ::base::PLATFORM_FILE_EXCLUSIVE_READ | 476 ::base::PLATFORM_FILE_EXCLUSIVE_READ |
454 ::base::PLATFORM_FILE_EXCLUSIVE_WRITE; 477 ::base::PLATFORM_FILE_EXCLUSIVE_WRITE;
455 bool created; 478 bool created;
456 ::base::PlatformFileError error_code; 479 ::base::PlatformFileError error_code;
457 ::base::PlatformFile file = ::base::CreatePlatformFile( 480 ::base::PlatformFile file = ::base::CreatePlatformFile(
458 CreateFilePath(fname), flags, &created, &error_code); 481 CreateFilePath(fname), flags, &created, &error_code);
459 if (error_code != ::base::PLATFORM_FILE_OK) { 482 if (error_code != ::base::PLATFORM_FILE_OK) {
460 result = Status::IOError(fname, PlatformFileErrorString(error_code)); 483 result = Status::IOError(fname, PlatformFileErrorString(error_code));
461 LogToUMA(kLockFile); 484 uma_logger_->RecordErrorAt(kLockFile);
462 } else { 485 } else {
463 ChromiumFileLock* my_lock = new ChromiumFileLock; 486 ChromiumFileLock* my_lock = new ChromiumFileLock;
464 my_lock->file_ = file; 487 my_lock->file_ = file;
465 *lock = my_lock; 488 *lock = my_lock;
466 } 489 }
467 return result; 490 return result;
468 } 491 }
469 492
470 virtual Status UnlockFile(FileLock* lock) { 493 virtual Status UnlockFile(FileLock* lock) {
471 ChromiumFileLock* my_lock = reinterpret_cast<ChromiumFileLock*>(lock); 494 ChromiumFileLock* my_lock = reinterpret_cast<ChromiumFileLock*>(lock);
472 Status result; 495 Status result;
473 if (!::base::ClosePlatformFile(my_lock->file_)) { 496 if (!::base::ClosePlatformFile(my_lock->file_)) {
474 result = Status::IOError("Could not close lock file."); 497 result = Status::IOError("Could not close lock file.");
475 LogToUMA(kUnlockFile); 498 uma_logger_->RecordErrorAt(kUnlockFile);
476 } 499 }
477 delete my_lock; 500 delete my_lock;
478 return result; 501 return result;
479 } 502 }
480 503
481 virtual void Schedule(void (*function)(void*), void* arg); 504 virtual void Schedule(void (*function)(void*), void* arg);
482 505
483 virtual void StartThread(void (*function)(void* arg), void* arg); 506 virtual void StartThread(void (*function)(void* arg), void* arg);
484 507
485 virtual std::string UserIdentifier() { 508 virtual std::string UserIdentifier() {
486 #if defined(OS_WIN) 509 #if defined(OS_WIN)
487 std::wstring user_sid; 510 std::wstring user_sid;
488 bool ret = ::base::win::GetUserSidString(&user_sid); 511 bool ret = ::base::win::GetUserSidString(&user_sid);
489 DCHECK(ret); 512 DCHECK(ret);
490 return UTF16ToUTF8(user_sid); 513 return UTF16ToUTF8(user_sid);
491 #else 514 #else
492 char buf[100]; 515 char buf[100];
493 snprintf(buf, sizeof(buf), "%d", int(geteuid())); 516 snprintf(buf, sizeof(buf), "%d", int(geteuid()));
494 return buf; 517 return buf;
495 #endif 518 #endif
496 } 519 }
497 520
498 virtual Status GetTestDirectory(std::string* path) { 521 virtual Status GetTestDirectory(std::string* path) {
499 mu_.Acquire(); 522 mu_.Acquire();
500 if (test_directory_.empty()) { 523 if (test_directory_.empty()) {
501 if (!::file_util::CreateNewTempDirectory(kLevelDBTestDirectoryPrefix, 524 if (!::file_util::CreateNewTempDirectory(kLevelDBTestDirectoryPrefix,
502 &test_directory_)) { 525 &test_directory_)) {
503 mu_.Release(); 526 mu_.Release();
504 LogToUMA(kGetTestDirectory); 527 uma_logger_->RecordErrorAt(kGetTestDirectory);
505 return Status::IOError("Could not create temp directory."); 528 return Status::IOError("Could not create temp directory.");
506 } 529 }
507 } 530 }
508 *path = FilePathToString(test_directory_); 531 *path = FilePathToString(test_directory_);
509 mu_.Release(); 532 mu_.Release();
510 return Status::OK(); 533 return Status::OK();
511 } 534 }
512 535
513 virtual Status NewLogger(const std::string& fname, Logger** result) { 536 virtual Status NewLogger(const std::string& fname, Logger** result) {
514 FILE* f = fopen_internal(fname.c_str(), "w"); 537 FILE* f = fopen_internal(fname.c_str(), "w");
515 if (f == NULL) { 538 if (f == NULL) {
516 *result = NULL; 539 *result = NULL;
517 LogToUMA(kNewLogger); 540 uma_logger_->RecordErrorAt(kNewLogger);
518 return Status::IOError(fname, strerror(errno)); 541 return Status::IOError(fname, strerror(errno));
519 } else { 542 } else {
520 if (!sync_parent(fname)) { 543 if (!sync_parent(fname)) {
521 fclose(f); 544 fclose(f);
522 return Status::IOError(fname, strerror(errno)); 545 return Status::IOError(fname, strerror(errno));
523 } 546 }
524 *result = new ChromiumLogger(f); 547 *result = new ChromiumLogger(f);
525 return Status::OK(); 548 return Status::OK();
526 } 549 }
527 } 550 }
528 551
529 virtual uint64_t NowMicros() { 552 virtual uint64_t NowMicros() {
530 return ::base::TimeTicks::Now().ToInternalValue(); 553 return ::base::TimeTicks::Now().ToInternalValue();
531 } 554 }
532 555
533 virtual void SleepForMicroseconds(int micros) { 556 virtual void SleepForMicroseconds(int micros) {
534 // Round up to the next millisecond. 557 // Round up to the next millisecond.
535 ::base::PlatformThread::Sleep(::base::TimeDelta::FromMicroseconds(micros)); 558 ::base::PlatformThread::Sleep(::base::TimeDelta::FromMicroseconds(micros));
536 } 559 }
537 560
561 protected:
562 scoped_ptr<UMALogger> uma_logger_;
563
538 private: 564 private:
539 // BGThread() is the body of the background thread 565 // BGThread() is the body of the background thread
540 void BGThread(); 566 void BGThread();
541 static void BGThreadWrapper(void* arg) { 567 static void BGThreadWrapper(void* arg) {
542 reinterpret_cast<ChromiumEnv*>(arg)->BGThread(); 568 reinterpret_cast<ChromiumEnv*>(arg)->BGThread();
543 } 569 }
544 570
545 FilePath test_directory_; 571 FilePath test_directory_;
546 572
547 size_t page_size_; 573 size_t page_size_;
548 ::base::Lock mu_; 574 ::base::Lock mu_;
549 ::base::ConditionVariable bgsignal_; 575 ::base::ConditionVariable bgsignal_;
550 bool started_bgthread_; 576 bool started_bgthread_;
551 577
552 // Entry per Schedule() call 578 // Entry per Schedule() call
553 struct BGItem { void* arg; void (*function)(void*); }; 579 struct BGItem { void* arg; void (*function)(void*); };
554 typedef std::deque<BGItem> BGQueue; 580 typedef std::deque<BGItem> BGQueue;
555 BGQueue queue_; 581 BGQueue queue_;
556 }; 582 };
557 583
558 ChromiumEnv::ChromiumEnv() 584 ChromiumEnv::ChromiumEnv()
559 : page_size_(::base::SysInfo::VMAllocationGranularity()), 585 : page_size_(::base::SysInfo::VMAllocationGranularity()),
560 bgsignal_(&mu_), 586 bgsignal_(&mu_),
561 started_bgthread_(false) { 587 started_bgthread_(false),
588 uma_logger_(new UMALogger("LevelDBEnv")) {
562 } 589 }
563 590
564 class Thread : public ::base::PlatformThread::Delegate { 591 class Thread : public ::base::PlatformThread::Delegate {
565 public: 592 public:
566 Thread(void (*function)(void* arg), void* arg) 593 Thread(void (*function)(void* arg), void* arg)
567 : function_(function), arg_(arg) { 594 : function_(function), arg_(arg) {
568 ::base::PlatformThreadHandle handle; 595 ::base::PlatformThreadHandle handle;
569 bool success = ::base::PlatformThread::Create(0, this, &handle); 596 bool success = ::base::PlatformThread::Create(0, this, &handle);
570 DCHECK(success); 597 DCHECK(success);
571 } 598 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 644
618 mu_.Release(); 645 mu_.Release();
619 (*function)(arg); 646 (*function)(arg);
620 } 647 }
621 } 648 }
622 649
623 void ChromiumEnv::StartThread(void (*function)(void* arg), void* arg) { 650 void ChromiumEnv::StartThread(void (*function)(void* arg), void* arg) {
624 new Thread(function, arg); // Will self-delete. 651 new Thread(function, arg); // Will self-delete.
625 } 652 }
626 653
654 class IDBEnv : public ChromiumEnv {
655 public:
656 IDBEnv() : ChromiumEnv() {
657 uma_logger_.reset(new UMALogger("LevelDBEnv.IDB"));
658 }
659 };
660
661 ::base::LazyInstance<IDBEnv>::Leaky
662 idb_env = LAZY_INSTANCE_INITIALIZER;
663
627 ::base::LazyInstance<ChromiumEnv>::Leaky 664 ::base::LazyInstance<ChromiumEnv>::Leaky
628 default_env = LAZY_INSTANCE_INITIALIZER; 665 default_env = LAZY_INSTANCE_INITIALIZER;
629 666
630 } 667 }
631 668
669 Env* IDBEnv() {
670 return idb_env.Pointer();
671 }
672
632 Env* Env::Default() { 673 Env* Env::Default() {
633 return default_env.Pointer(); 674 return default_env.Pointer();
634 } 675 }
635 676
636 } 677 }
OLDNEW
« no previous file with comments | « third_party/leveldatabase/README.chromium ('k') | third_party/leveldatabase/env_idb.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698