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