1 /*
2  * File:   ErrorContext.cpp
3  * Author: Yavor Nikolov
4  *
5  * Created on 29 October 2011, 18:14
6  */
7 
8 #include "pbzip2.h"
9 #include "ErrorContext.h"
10 
11 #include <cstring>
12 #include <cerrno>
13 
14 namespace pbzip2
15 {
16 
17 ErrorContext * ErrorContext::_instance = 0;
18 pthread_mutex_t ErrorContext::_err_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
19 
getInstance()20 ErrorContext * ErrorContext::getInstance()
21 {
22 	pthread_mutex_lock( &_err_ctx_mutex );
23 
24 	if ( ErrorContext::_instance == NULL )
25 	{
26 		_instance = new(std::nothrow) ErrorContext;
27 
28 		if ( _instance == NULL )
29 		{
30 			fprintf( stderr, "pbzip2: *ERROR: Can't initialize error context - out of memory!\n" );
31 		}
32 	}
33 
34 	pthread_mutex_unlock( &_err_ctx_mutex );
35 
36 	return _instance;
37 }
38 
printErrnoMsg(FILE * out,int err)39 void ErrorContext::printErrnoMsg( FILE * out, int err )
40 {
41 	if ( err != 0 )
42 	{
43 		fprintf( out, "pbzip2: *ERROR: system call failed with errno=[%d: %s]!\n",
44 			err, std::strerror( err ) );
45 	}
46 }
47 
syncPrintErrnoMsg(FILE * out,int err)48 void ErrorContext::syncPrintErrnoMsg( FILE * out, int err )
49 {
50 	pthread_mutex_lock( &_err_ctx_mutex );
51 	printErrnoMsg( out, err );
52 	pthread_mutex_unlock( &_err_ctx_mutex );
53 }
54 
printErrorMessages(FILE * out)55 void ErrorContext::printErrorMessages( FILE * out )
56 {
57 	pthread_mutex_lock( &_err_ctx_mutex );
58 
59 	printErrnoMsg( out, _first_kernel_err_no );
60 	printErrnoMsg( out, _last_kernel_err_no );
61 
62 	pthread_mutex_unlock( &_err_ctx_mutex );
63 }
64 
saveError()65 void ErrorContext::saveError()
66 {
67 	int newerr = errno;
68 
69 	pthread_mutex_lock( &_err_ctx_mutex );
70 
71 	if ( newerr != 0 )
72 	{
73 		int & err_ref = ( _first_kernel_err_no == 0 )
74 						? _first_kernel_err_no
75 						: _last_kernel_err_no;
76 
77 		err_ref = newerr;
78 	}
79 
80 	_last_kernel_err_no = errno;
81 
82 	pthread_mutex_unlock( &_err_ctx_mutex );
83 }
84 
reset()85 void ErrorContext::reset()
86 {
87 	pthread_mutex_lock( &_err_ctx_mutex );
88 	_first_kernel_err_no = _last_kernel_err_no = 0;
89 	pthread_mutex_unlock( &_err_ctx_mutex );
90 }
91 
92 } // namespace pbzip2
93