1/* 2 * Copyright 2012-2014, Rene Gollent, rene@gollent.com. 3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 4 * Distributed under the terms of the MIT License. 5 */ 6 7#include "Jobs.h" 8 9#include <AutoLocker.h> 10 11#include "Image.h" 12#include "ImageDebugInfo.h" 13#include "TeamDebugInfo.h" 14#include "Team.h" 15 16 17// #pragma mark - LoadImageDebugInfoJob 18 19 20LoadImageDebugInfoJob::LoadImageDebugInfoJob(Image* image) 21 : 22 fKey(image, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO), 23 fImage(image), 24 fState() 25{ 26 fImage->AcquireReference(); 27 28 SetDescription("Loading debugging information for %s", 29 fImage->Name().String()); 30} 31 32 33LoadImageDebugInfoJob::~LoadImageDebugInfoJob() 34{ 35 fImage->ReleaseReference(); 36} 37 38 39const JobKey& 40LoadImageDebugInfoJob::Key() const 41{ 42 return fKey; 43} 44 45 46status_t 47LoadImageDebugInfoJob::Do() 48{ 49 // get an image info for the image 50 AutoLocker<Team> locker(fImage->GetTeam()); 51 ImageInfo imageInfo(fImage->Info()); 52 locker.Unlock(); 53 54 // create the debug info 55 ImageDebugInfo* debugInfo; 56 status_t error = fImage->GetTeam()->DebugInfo()->LoadImageDebugInfo( 57 imageInfo, fImage->ImageFile(), fState, debugInfo); 58 59 // set the result 60 locker.Lock(); 61 62 if (fState.UserInputRequired()) { 63 return WaitForUserInput(); 64 } else if (error == B_OK) { 65 error = fImage->SetImageDebugInfo(debugInfo, IMAGE_DEBUG_INFO_LOADED); 66 debugInfo->ReleaseReference(); 67 } else 68 fImage->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_UNAVAILABLE); 69 70 return error; 71} 72 73 74/*static*/ status_t 75LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, Image* image, 76 JobListener* listener, ImageDebugInfo** _imageDebugInfo) 77{ 78 AutoLocker<Team> teamLocker(image->GetTeam()); 79 80 // If already loaded, we're done. 81 if (image->GetImageDebugInfo() != NULL) { 82 if (_imageDebugInfo != NULL) { 83 *_imageDebugInfo = image->GetImageDebugInfo(); 84 (*_imageDebugInfo)->AcquireReference(); 85 } 86 return B_OK; 87 } 88 89 // If already loading, the caller has to wait, if desired. 90 if (image->ImageDebugInfoState() == IMAGE_DEBUG_INFO_LOADING) { 91 if (_imageDebugInfo != NULL) 92 *_imageDebugInfo = NULL; 93 return B_OK; 94 } 95 96 // If an earlier load attempt failed, bail out. 97 if (image->ImageDebugInfoState() != IMAGE_DEBUG_INFO_NOT_LOADED) 98 return B_ERROR; 99 100 // schedule a job 101 LoadImageDebugInfoJob* job = new(std::nothrow) LoadImageDebugInfoJob( 102 image); 103 if (job == NULL) 104 return B_NO_MEMORY; 105 106 status_t error = worker->ScheduleJob(job, listener); 107 if (error != B_OK) { 108 image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_UNAVAILABLE); 109 return error; 110 } 111 112 image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_LOADING); 113 114 if (_imageDebugInfo != NULL) 115 *_imageDebugInfo = NULL; 116 return B_OK; 117} 118