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