OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 #ifndef CRASHPAD_HANDLER_MAC_CRASH_REPORT_UPLOAD_THREAD_H_ | |
16 #define CRASHPAD_HANDLER_MAC_CRASH_REPORT_UPLOAD_THREAD_H_ | |
17 | |
18 #include "base/basictypes.h" | |
19 | |
20 #include <pthread.h> | |
21 | |
22 #include <string> | |
23 | |
24 #include "client/crash_report_database.h" | |
25 #include "util/synchronization/semaphore.h" | |
26 | |
27 namespace crashpad { | |
28 | |
29 //! \brief A thread that processes pending crash reports in a | |
30 //! CrashReportDatabase by uploading them or marking them as completed | |
31 //! without upload, as desired. | |
32 //! | |
33 //! A producer of crash reports should notify an object of this class that a new | |
34 //! report has been added to the database by calling ReportPending(). | |
35 //! | |
36 //! Independently of being triggered by ReportPending(), objects of this class | |
37 //! periodically examine the database for pending reports. This allows failed | |
38 //! upload attempts for reports left in the pending state to be retried. It also | |
39 //! catches reports that are added without a ReportPending() signal being | |
40 //! caught. This may happen if crash reports are added to the database by other | |
41 //! processes. | |
42 class CrashReportUploadThread { | |
43 public: | |
44 //! \brief Constructs a new object. | |
45 //! | |
46 //! \param[in] database The database to upload crash reports from. | |
47 //! \param[in] url The URL of the server to upload crash reports to. | |
48 CrashReportUploadThread(CrashReportDatabase* database, | |
49 const std::string& url); | |
50 ~CrashReportUploadThread(); | |
51 | |
52 //! \brief Starts a dedicated upload thread, which executes ThreadMain(). | |
53 //! | |
54 //! This method may only be be called on a newly-constructed object or after | |
55 //! a call to Stop(). | |
56 void Start(); | |
57 | |
58 //! \brief Stops the upload thread. | |
59 //! | |
60 //! The upload thread will terminate after completing whatever task it is | |
61 //! performing. If it is not performing any task, it will terminate | |
62 //! immediately. This method blocks while waiting for the upload thread to | |
63 //! terminate. | |
64 //! | |
65 //! This method must only be called after Start(). If Start() has been called, | |
66 //! this method must be called before destroying an object of this class. | |
67 //! | |
68 //! This method may be called from any thread other than the upload thread. | |
69 //! It is expected to only be called from the same thread that called Start(). | |
70 void Stop(); | |
71 | |
72 //! \brief Informs the upload thread that a new pending report has been added | |
73 //! to the database. | |
74 //! | |
75 //! This method may be called from any thread. | |
76 void ReportPending(); | |
77 | |
78 private: | |
79 //! \brief The result code from UploadReport(). | |
80 enum class UploadResult { | |
81 //! \brief The crash report was uploaded successfully. | |
82 kSuccess, | |
83 | |
84 //! \brief The crash report upload failed in such a way that recovery is | |
85 //! impossible. | |
86 //! | |
87 //! No further upload attempts should be made for the report. | |
88 kPermanentFailure, | |
89 | |
90 //! \brief The crash report upload failed, but it might succeed again if | |
91 //! retried in the future. | |
92 //! | |
93 //! If the report has not already been retried too many times, the caller | |
94 //! may arrange to call UploadReport() for the report again in the future, | |
95 //! after a suitable delay. | |
96 kRetry, | |
97 }; | |
98 | |
99 //! \brief Calls ProcessPendingReports() in response to ReportPending() having | |
100 //! been called on any thread, as well as periodically on a timer. | |
101 void ThreadMain(); | |
102 | |
103 //! \brief Obtains all pending reports from the database, and calls | |
104 //! ProcessPendingReport() to process each one. | |
105 void ProcessPendingReports(); | |
106 | |
107 //! \brief Processes a single pending report from the database. | |
108 //! | |
109 //! \param[in] report The crash report to process. | |
110 //! | |
111 //! If report upload is enabled, this method attempts to upload \a report by | |
112 //! calling UplaodReport(). If the upload is successful, the report will be | |
113 //! marked as “completed” in the database. If the upload fails and more | |
114 //! retries are desired, the report’s upload-attempt count and | |
115 //! last-upload-attempt time will be updated in the database and it will | |
116 //! remain in the “pending” state. If the upload fails and no more retries are | |
117 //! desired, or report upload is disabled, it will be marked as “completed” in | |
118 //! the database without ever having been uploaded. | |
119 void ProcessPendingReport(const CrashReportDatabase::Report& report); | |
120 | |
121 //! \brief Attempts to upload a crash report. | |
122 //! | |
123 //! \param[in] report The report to upload. The caller is responsible for | |
124 //! calling CrashReportDatabase::GetReportForUploading() before calling | |
125 //! this method, and for calling | |
126 //! CrashReportDatabase::RecordUploadAttempt() after calling this method. | |
127 //! \param[out] response_body If the upload attempt is successful, this will | |
128 //! be set to the response body sent by the server. Breakpad-type servers | |
129 //! provide the crash ID assigned by the server in the response body. | |
130 //! | |
131 //! \return A member of UploadResult indicating the result of the upload | |
132 //! attempt. | |
133 UploadResult UploadReport(const CrashReportDatabase::Report* report, | |
134 std::string* response_body); | |
135 | |
136 //! \brief Cals ThreadMain(). | |
137 //! | |
138 //! \param[in] arg A pointer to the object on which to invoke ThreadMain(). | |
139 //! | |
140 //! \return `nullptr`. | |
141 static void* RunThreadMain(void* arg); | |
142 | |
143 std::string url_; | |
144 CrashReportDatabase* database_; // weak | |
145 Semaphore semaphore_; // TODO(mark): Use a condition variable instead? | |
146 pthread_t thread_; | |
147 bool running_; | |
148 }; | |
149 | |
150 } // namespace crashpad | |
151 | |
152 #endif // CRASHPAD_HANDLER_MAC_CRASH_REPORT_UPLOAD_THREAD_H_ | |
OLD | NEW |