| 173 | } |
| 174 | |
| 175 | void xlog(int level, const char *msg, ...) // log line from any thread (more expensive: only use for functions, that are called from main and other threads) |
| 176 | { |
| 177 | ASSERT(level >= 0 && level < ACLOG_NUM); |
| 178 | if(!loglevelenabled[level]) return; |
| 179 | bool ismain = ismainthread(); |
| 180 | if(ismain) |
| 181 | { |
| 182 | if(mainlog.full()) { mainlogoverflow++; return; } // do. not. block. |
| 183 | } |
| 184 | else |
| 185 | { |
| 186 | threadlogsem.wait(); // properly lock, so different threads can use this |
| 187 | while(threadlog.full()) threadlogfullsem.wait(); // wait for buffer to clear |
| 188 | } |
| 189 | logline_s *ll = ismain ? mainlog.stage(new logline_s) : threadlog.stage(new logline_s); |
| 190 | vformatstring(ll->msg, msg, msg); |
| 191 | filtertext(ll->msg, ll->msg, FTXT__LOG); |
| 192 | ll->t = time(NULL); |
| 193 | ll->level = level; |
| 194 | if(ismain) |
| 195 | { |
| 196 | mainlog.commit(); |
| 197 | if(mainlogsem.getvalue() < 1) mainlogsem.post(); |
| 198 | } |
| 199 | else |
| 200 | { |
| 201 | threadlog.commit(); |
| 202 | threadlogsem.post(); |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | extern int stat_theadlog_peaklevel; |
| 207 |
no test coverage detected