@@ -62,8 +62,7 @@ File::File(const struct cfg_file &cfg, ipx_ctx_t *ctx) : Output(cfg.name, ctx)
6262{
6363 // Prepare a configuration of the thread for changing time windows
6464 _thread = new thread_ctx_t ;
65- _thread->new_file = nullptr ;
66- _thread->new_file_ready = false ;
65+ _thread->file = nullptr ;
6766 _thread->stop = false ;
6867
6968 _thread->ctx = ctx;
@@ -96,17 +95,33 @@ File::File(const struct cfg_file &cfg, ipx_ctx_t *ctx) : Output(cfg.name, ctx)
9695 throw std::runtime_error (" (File output) Failed to create a time window file." );
9796 }
9897
99- _file = new_file;
98+ _thread-> file = new_file;
10099
101- if (pthread_mutex_init (&_thread->mutex , NULL ) != 0 ) {
102- fclose (_file);
100+ pthread_rwlockattr_t attr;
101+ if (pthread_rwlockattr_init (&attr) != 0 ) {
102+ fclose (_thread->file );
103103 delete _thread;
104- throw std::runtime_error (" (File output) Mutex initialization failed!" );
104+ throw std::runtime_error (" (File output) Rwlockattr initialization failed!" );
105105 }
106106
107+ if (pthread_rwlockattr_setkind_np (&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) != 0 ) {
108+ fclose (_thread->file );
109+ pthread_rwlockattr_destroy (&attr);
110+ delete _thread;
111+ throw std::runtime_error (" (File output) Rwlockattr setkind failed!" );
112+ }
113+
114+ if (pthread_rwlock_init (&_thread->rwlock , &attr) != 0 ) {
115+ fclose (_thread->file );
116+ pthread_rwlockattr_destroy (&attr);
117+ delete _thread;
118+ throw std::runtime_error (" (File output) Rwlock initialization failed!" );
119+ }
120+
121+ pthread_rwlockattr_destroy (&attr);
107122 if (pthread_create (&_thread->thread , NULL , &File::thread_window, _thread) != 0 ) {
108- fclose (_file );
109- pthread_mutex_destroy (&_thread->mutex );
123+ fclose (_thread-> file );
124+ pthread_rwlock_destroy (&_thread->rwlock );
110125 delete _thread;
111126 throw std::runtime_error (" (File output) Failed to start a thread for changing time "
112127 " windows." );
@@ -120,17 +135,13 @@ File::File(const struct cfg_file &cfg, ipx_ctx_t *ctx) : Output(cfg.name, ctx)
120135 */
121136File::~File ()
122137{
123- if (_file) {
124- fclose (_file);
125- }
126-
127138 if (_thread) {
128139 _thread->stop = true ;
129140 pthread_join (_thread->thread , NULL );
130- pthread_mutex_destroy (&_thread->mutex );
141+ pthread_rwlock_destroy (&_thread->rwlock );
131142
132- if (_thread->new_file ) {
133- fclose (_thread->new_file );
143+ if (_thread->file ) {
144+ fclose (_thread->file );
134145 }
135146
136147 delete _thread;
@@ -164,10 +175,10 @@ File::thread_window(void *context)
164175 }
165176
166177 // New time window
167- pthread_mutex_lock (&data->mutex );
168- if (data->new_file ) {
169- fclose (data->new_file );
170- data->new_file = NULL ;
178+ pthread_rwlock_wrlock (&data->rwlock );
179+ if (data->file ) {
180+ fclose (data->file );
181+ data->file = nullptr ;
171182 }
172183
173184 data->window_time += data->window_size ;
@@ -177,9 +188,8 @@ File::thread_window(void *context)
177188 }
178189
179190 // Null pointer is also valid...
180- data->new_file = file;
181- data->new_file_ready = true ;
182- pthread_mutex_unlock (&data->mutex );
191+ data->file = file;
192+ pthread_rwlock_unlock (&data->rwlock );
183193 }
184194
185195 IPX_CTX_DEBUG (data->ctx , " (File output) Thread terminated." , ' \0 ' );
@@ -196,28 +206,23 @@ File::thread_window(void *context)
196206int
197207File::process (const char *str, size_t len)
198208{
199- // Should we change a time window
200- if (_thread->new_file_ready ) {
201- // Close old time window
202- if (_file) {
203- fclose (_file);
204- }
205-
206- // Get new time window
207- pthread_mutex_lock (&_thread->mutex );
208- _file = _thread->new_file ;
209- _thread->new_file = nullptr ;
210- _thread->new_file_ready = false ;
211- pthread_mutex_unlock (&_thread->mutex );
209+ pthread_rwlock_rdlock (&_thread->rwlock );
210+ if (_thread->file ) {
211+ // Store the record
212+ fwrite (str, len, 1 , _thread->file );
212213 }
214+ pthread_rwlock_unlock (&_thread->rwlock );
215+ return IPX_OK;
216+ }
213217
214- if (!_file) {
215- return IPX_OK;
218+ void
219+ File::flush ()
220+ {
221+ pthread_rwlock_rdlock (&_thread->rwlock );
222+ if (_thread->file ) {
223+ fflush (_thread->file );
216224 }
217-
218- // Store the record
219- fwrite (str, len, 1 , _file);
220- return IPX_OK;
225+ pthread_rwlock_unlock (&_thread->rwlock );
221226}
222227
223228/* *
0 commit comments