rpm  5.4.15
rpmzlog.c
Go to the documentation of this file.
1 
6 /* pigz.c -- parallel implementation of gzip
7  * Copyright (C) 2007, 2008 Mark Adler
8  * Version 2.1.4 9 Nov 2008 Mark Adler
9  */
10 
11 /*
12  This software is provided 'as-is', without any express or implied
13  warranty. In no event will the author be held liable for any damages
14  arising from the use of this software.
15 
16  Permission is granted to anyone to use this software for any purpose,
17  including commercial applications, and to alter it and redistribute it
18  freely, subject to the following restrictions:
19 
20  1. The origin of this software must not be misrepresented; you must not
21  claim that you wrote the original software. If you use this software
22  in a product, an acknowledgment in the product documentation would be
23  appreciated but is not required.
24  2. Altered source versions must be plainly marked as such, and must not be
25  misrepresented as being the original software.
26  3. This notice may not be removed or altered from any source distribution.
27 
28  Mark Adler
29  madler@alumni.caltech.edu
30 
31  Mark accepts donations for providing this software. Donations are not
32  required or expected. Any amount that you feel is appropriate would be
33  appreciated. You can use this link:
34 
35  https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=536055
36 
37  */
38 
39 #include "system.h"
40 #include <stdarg.h>
41 
42 #include <rpmiotypes.h>
43 #include "yarn.h"
44 
45 #define _RPMZLOG_INTERNAL
46 #include "rpmzlog.h"
47 
48 #include "debug.h"
49 
50 /*@unchecked@*/
51 static int _rpmzlog_debug = 0;
52 
53 /*@access rpmzMsg @*/
54 /*@access rpmzLog @*/
55 
56 
57 #ifdef __cplusplus
58 GENfree(rpmzMsg)
59 GENfree(rpmzLog)
60 #endif /* __cplusplus */
61 
62 /*==============================================================*/
63 
64 /* maximum log entry length */
65 #define _RPMZLOG_MAXMSG 256
66 
68 {
69  long nrefs;
70 
71  if (zlog == NULL)
72  return NULL;
73  yarnPossess(zlog->_item.use);
74  nrefs = yarnPeekLock(zlog->_item.use);
75 if (_rpmzlog_debug)
76 fprintf(stderr, " ++ zlog %p[%ld]\n", zlog, nrefs+1);
77  yarnTwist(zlog->_item.use, BY, 1);
78  return zlog;
79 }
80 
81 rpmzLog rpmzLogNew(struct timeval *tv)
82 {
83  rpmzLog zlog = (rpmzLog) xcalloc(1, sizeof(*zlog));
84 
85  zlog->_item.use = yarnNewLock(0);
86  zlog->msg_head = NULL;
87  zlog->msg_tail = &zlog->msg_head;
88 
89  /* starting time for log entries */
90 /*@-assignexpose@*/
91  if (tv != NULL)
92  zlog->start = *tv; /* structure assignment */
93  else
94  (void) gettimeofday(&zlog->start, NULL);
95 /*@=assignexpose@*/
96 /*@-nullret@*/
97  return rpmzLogLink(zlog);
98 /*@=nullret@*/
99 }
100 
101 void rpmzLogAdd(rpmzLog zlog, const char *fmt, ...)
102 {
103  rpmzMsg me;
104  struct timeval now;
105  va_list ap;
106  char msg[_RPMZLOG_MAXMSG];
107  int xx;
108 
109  if (zlog == NULL)
110  return;
111 
112  xx = gettimeofday(&now, NULL);
113  me = (rpmzMsg) xmalloc(sizeof(*me));
114  me->when = now;
115  va_start(ap, fmt);
116  xx = vsnprintf(msg, sizeof(msg)-1, fmt, ap);
117  va_end(ap);
118  msg[sizeof(msg)-1] = '\0';
119 
120 /*@-mustfreeonly@*/
121  me->msg = (char *) xmalloc(strlen(msg) + 1);
122 /*@=mustfreeonly@*/
123  strcpy(me->msg, msg);
124 /*@-mustfreeonly@*/
125  me->next = NULL;
126 /*@=mustfreeonly@*/
127 
128 assert(zlog->_item.use != NULL);
129  yarnPossess(zlog->_item.use);
130  *zlog->msg_tail = me;
131  zlog->msg_tail = &me->next;
132  zlog->msg_count++;
133  yarnRelease(zlog->_item.use);
134 }
135 
139 static int rpmzMsgShow(/*@null@*/ rpmzLog zlog, /*@null@*/ FILE * fp)
140  /*@globals fileSystem, internalState @*/
141  /*@modifies zlog, *fp, fileSystem, internalState @*/
142 {
143  rpmzMsg me;
144  struct timeval diff;
145 
146  if (zlog == NULL)
147  return 0;
148  if (fp == NULL)
149  fp = stderr;
150 
151  yarnPossess(zlog->_item.use);
152  if (zlog->msg_tail == NULL || (me = zlog->msg_head) == NULL) {
153  yarnRelease(zlog->_item.use);
154  return 0;
155  }
156  zlog->msg_head = me->next;
157  if (me->next == NULL)
158  zlog->msg_tail = &zlog->msg_head;
159  zlog->msg_count--;
160  yarnRelease(zlog->_item.use);
161 
162  diff.tv_usec = me->when.tv_usec - zlog->start.tv_usec;
163  diff.tv_sec = me->when.tv_sec - zlog->start.tv_sec;
164  if (diff.tv_usec < 0) {
165  diff.tv_usec += 1000000L;
166  diff.tv_sec--;
167  }
168  fprintf(fp, "trace %ld.%06ld %s\n",
169  (long)diff.tv_sec, (long)diff.tv_usec, me->msg);
170  (void) fflush(fp);
171  me->msg = _free(me->msg);
172  me = _free(me);
173  return 1;
174 }
175 
177 {
178  long nrefs;
179  rpmzMsg me;
180 
181  if (zlog == NULL)
182  return NULL;
183 
184  yarnPossess(zlog->_item.use);
185  nrefs = yarnPeekLock(zlog->_item.use);
186 if (_rpmzlog_debug)
187 fprintf(stderr, " -- zlog %p[%ld]\n", zlog, nrefs);
188 #ifdef NOTYET
189 assert(nrefs > 0);
190 #else
191 if (nrefs <= 0)
192 fprintf(stderr, "==> FIXME: %s: zlog %p[%ld]\n", __FUNCTION__, zlog, nrefs);
193 #endif
194  if (nrefs == 1) {
195  yarnLock use = zlog->_item.use;
196  if (zlog->msg_tail != NULL) {
197  while ((me = zlog->msg_head) != NULL) {
198  zlog->msg_head = me->next;
199  me->msg = _free(me->msg);
200 /*@-compdestroy@*/
201  me = _free(me);
202 /*@=compdestroy@*/
203  zlog->msg_count--;
204  }
205 #ifdef NOTYET
206 assert(zlog->msg_count == 0);
207 #else
208 if (zlog->msg_count != 0)
209 fprintf(stderr, "==> FIXME: %s: zlog %p[%ld] count %d\n", __FUNCTION__, zlog, nrefs, zlog->msg_count);
210 #endif
211  zlog->msg_count = 0;
212  zlog->msg_tail = NULL;
213  }
214  zlog = _free(zlog);
215  yarnTwist(use, BY, -1);
216  use = yarnFreeLock(use);
217  } else
218  yarnTwist(zlog->_item.use, BY, -1);
219  return NULL;
220 }
221 
222 rpmzLog rpmzLogDump(rpmzLog zlog, FILE * fp)
223 {
224  while (rpmzMsgShow(zlog, fp))
225  {;}
226 
227  return rpmzLogFree(zlog);
228 }
rpmzLog rpmzLogLink(rpmzLog zlog)
Reference the log data.
Definition: rpmzlog.c:67
void yarnTwist(yarnLock bolt, yarnTwistOP op, long val)
Definition: yarn.c:279
void rpmzLogAdd(rpmzLog zlog, const char *fmt,...)
Add entry to trace log.
Definition: rpmzlog.c:101
void yarnPossess(yarnLock bolt)
Definition: yarn.c:262
long yarnPeekLock(yarnLock bolt)
Definition: yarn.c:325
rpmzLog rpmzLogDump(rpmzLog zlog, FILE *fp)
Show entries until no more, free log.
Definition: rpmzlog.c:222
Job queue and buffer pool management.
rpmzLog rpmzLogFree(rpmzLog zlog)
Release a reference to the log data.
Definition: rpmzlog.c:176
static int rpmzMsgShow(rpmzLog zlog, FILE *fp)
Definition: rpmzlog.c:139
#define _RPMZLOG_MAXMSG
Definition: rpmzlog.c:65
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:300
static int _rpmzlog_debug
Definition: rpmzlog.c:51
struct rpmzLog_s * rpmzLog
trace log pointer
Definition: rpmzlog.h:11
yarnLock yarnNewLock(long initial)
Definition: yarn.c:248
yarnLock yarnFreeLock(yarnLock bolt)
Definition: yarn.c:330
void yarnRelease(yarnLock bolt)
Definition: yarn.c:270
#define L(CS)
Definition: fnmatch.c:161
static int vsnprintf(char *buf, int nb, const char *fmt, va_list ap)
Definition: rpmps.c:212
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
rpmzLog rpmzLogNew(struct timeval *tv)
Set up log (call from main thread before other threads launched).
Definition: rpmzlog.c:81
Definition: yarn.h:166
#define xmalloc
Definition: system.h:32