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
LoadImageDebugInfoJob(Image * image)20 LoadImageDebugInfoJob::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
~LoadImageDebugInfoJob()33 LoadImageDebugInfoJob::~LoadImageDebugInfoJob()
34 {
35 fImage->ReleaseReference();
36 }
37
38
39 const JobKey&
Key() const40 LoadImageDebugInfoJob::Key() const
41 {
42 return fKey;
43 }
44
45
46 status_t
Do()47 LoadImageDebugInfoJob::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
ScheduleIfNecessary(Worker * worker,Image * image,JobListener * listener,ImageDebugInfo ** _imageDebugInfo)75 LoadImageDebugInfoJob::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