libraries/clogger/inc/CloggerServer.h
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // CloggerServer.h
       
     2 // 
       
     3 // Copyright (c) 2006 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #ifndef CLOGGERSERVER_H
       
    14 #define CLOGGERSERVER_H
       
    15 
       
    16 #include "SensibleServer.h"
       
    17 #include <babitflags.h>
       
    18 #include <e32hashtab.h>
       
    19 #include <e32msgqueue.h>
       
    20 #include "debugrouter.h"
       
    21 
       
    22 class CCloggerServer;
       
    23 class MWriter;
       
    24 class CLogsDirWatcher;
       
    25 class CSyncWriterWrapper;
       
    26 class CDebugRouterClient;
       
    27 class CSessionWriter;
       
    28 class CSessionWriterSession;
       
    29 class CSessionWriterServer;
       
    30 
       
    31 class CCloggerSession : public CSensibleSession
       
    32 	{
       
    33 public:
       
    34 	CCloggerSession();
       
    35 
       
    36 private:
       
    37 	TBool DoServiceL(const RMessage& aMessage);
       
    38 
       
    39 	inline CCloggerServer& Server();
       
    40 	~CCloggerSession();
       
    41 
       
    42 public:
       
    43 	TAny* iContext;
       
    44 	RBuf8 iGetTagStatesContext;
       
    45 	RChunk iPerformanceLoggingChunk; // Only used by the high performance logging library clogger-buffered.dll
       
    46 	};
       
    47 
       
    48 class CCloggerServer : public CSensibleServer
       
    49 	{
       
    50 public:
       
    51 	CCloggerServer();
       
    52 	~CCloggerServer();
       
    53 	void ConstructL();
       
    54 
       
    55 	TBool DoServiceL(const RMessage& aMessage);
       
    56 
       
    57 	// Functions to be called by the session
       
    58 	inline RBuf8& SessionTempBuf() { iSessionTempBuf.Zero(); return iSessionTempBuf; }
       
    59 	void Log(TAny* aContext, const TDesC8& aLine, TUint32 aTickCount); // aContext can be NULL to indicate KCloggerTag
       
    60 	TUint32 TagEnabled(const TAny* aContext, TInt* aCurrentSequenceNumber = NULL);
       
    61 	void WriteCallbackForGetTagStatesL(TCallbackWriter& aWriter);
       
    62 	TAny* NewSessionForTagL(HBufC8* aTag); // Takes ownership at end. Returns an opaque identifier for this tag (which may have been shared with other sessions)
       
    63 	TAny* NewSessionForTag(HBufC8* aTag);
       
    64 	void ReplaceTagL(TAny*& aCurrentContext, HBufC8* aNewTag); // If the tag for aCurrentContext hasn't been used yet, deletes it from the tag list. In either case, it then calls NewSessionForTagL. Takes ownership of both arguments if nothing leaves
       
    65 	void DropSession(CCloggerSession* aSession);
       
    66 	void HexDumpL(TAny* aContext, const TDesC8& aHeader, const TDesC8& aData, TUint32 aTickCount);
       
    67 	void RegisterDisabledLog(TAny* aContext);
       
    68 	void UpdatedBuffers(TBool aAboutToCloseBuffers=EFalse); // Registers the log buffers with the debug router, so they can be recorded in a crash log (if supported by the baseport)
       
    69 	TInt CreateKernChunkForClient(RThread* aClient, TInt aMaxSize, TInt aCommittedSize, RChunk& aOurChunk);
       
    70 	CSessionWriter* RegisterSessionWithSessionWriter(CSessionWriterSession* aSession);
       
    71 	RChunk& GetBufChunk();
       
    72 	static void ThreadPrettyName(TDes8& aName);
       
    73 	TBool ForceBreakpointRequested() const;
       
    74 
       
    75 	void LogsDirHasBeenCreated();
       
    76 	void ResetIdleWriteTimer();
       
    77 
       
    78 	// Functions to be called by writers (eg CLogFile, RDebug::Print thingy)
       
    79 	const TDesC8& GetBuf(TInt aIdx); // Increments ref count. May be called from other threads
       
    80 	void CompletedWritingBuf(MWriter* aWriter, TInt aBuf); // Tells the server that aWriter has finished writing aBuf. If all writers have finished with this buffer then the buffer is marked ready to use. Must be called from main thread.
       
    81 	TDes& GetFilenameToRotate(); // Should only be called by iCompressor, but may be called from its SyncWriter thread. iCompressor should update the name to indicate the new file it has created (so that ECopyRotatedToExternalMedia will work)
       
    82 
       
    83 	void LogKernMessage(TUint8 aWhere, TUint32 aTickCount, TUint aThreadId, const TDesC8& aMsg); //  Should only be called by CDebugRouterClient
       
    84 	void LogHighPerformanceBuffer(const TDesC8& aBuf);
       
    85 	void LogError(TRefByValue<const TDesC8> aFmt, ...);
       
    86 
       
    87 private:
       
    88 	TInt TransientServerShutdownTime() const;
       
    89 	CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
       
    90 	void LogLine(const TDesC8& aLine);
       
    91 	void CloseBuffers(); // Deletes all buffers and removes them from iBufs
       
    92 	void FlushBuffers();
       
    93 	void GotoNextBufL(); // Sets iCurrent to the next empty buffer, or allocates one if there isn't a free one. Also tells writers to get cracking if they aren't already busy
       
    94 	void GetSettingsL();
       
    95 	void DoGetSettingsL();
       
    96 	void PersistSettingsL();
       
    97 	void ResetSettingsL();
       
    98 	void UpdateBufferSizeL(TInt aSize, TInt aNum);
       
    99 	static TInt StaticIdleTimerExpired(TAny* aThis);
       
   100 	void IdleTimerExpired();
       
   101 	TUint GetEnabledWriters() const;
       
   102 	void Rotate(const RMessage* aMessage = NULL);
       
   103 	void LogNote(TUint32 aLogMask, TRefByValue<const TDesC8> aFmt, ...);
       
   104 	void DoLogErrorOrNote(TUint32 aLogMask, const TDesC8 &aFmt, VA_LIST args);
       
   105 	void CopyLogToExternalMediaL(TDes& aFile);
       
   106 	class TTagData; // I see now why the coding standards say declare inner classes etc at the start of the class declaration...
       
   107 	void NotifySessionsOfChangedTag(TTagData* aTag);
       
   108 	void SetKernelLoggingL(TBool aEnable);
       
   109 	void UpdatedGlobalOptionsL(TUint aOldOptions);
       
   110 	void TellAllWritersToWriteBuf(TInt aBuf);
       
   111 	void TellWriterToWriteBuf(TInt aWriterId, TInt aBuf);
       
   112 	void ReCalculateFileAlignment();
       
   113 	TInt OpenLogFile();
       
   114 	TInt AdjustBufferChunk(TInt aNewSize);
       
   115 	inline TTime TickCountToTime(TUint32 aTickCount) const;
       
   116 
       
   117 private:
       
   118 	// Buffers
       
   119 	class TBufEntry {
       
   120 	public:
       
   121 		TBufEntry() : iBuf(NULL, 0), iArrayIdx(-1), iNext(NULL), iBufferBusy(0) {}
       
   122 
       
   123 		//RBuf8 iBuf;
       
   124 		TPtr8 iBuf;
       
   125 		TInt iArrayIdx;
       
   126 		TBufEntry* iNext;
       
   127 		TUint iBufferBusy; // This is used to track when all the different consumers of the buffer (RDebug, Bluetooth, File etc) are finished with it
       
   128 		};
       
   129 	RPointerArray<TBufEntry> iBufs;
       
   130 	TBufEntry* iCurrent;
       
   131 	TInt iSubtractSizeOfNextBuffer;
       
   132 	RBuf8 iSessionTempBuf; // Used by sessions for reading descriptor from client
       
   133 	RBuf8 iTempBuf; // Used for formatting line with timestamp and tag
       
   134 	RChunk iChunkForBufs; // Use a separate chunk so we can map into crashlogs
       
   135 
       
   136 	// Miscellaneous stuff used when doing flushes and sync writes
       
   137 	CActiveSchedulerWait iFlushBufferWait;
       
   138 	const TDesC8* iSyncWriteBuffer; // This is only used when doing synchronous writing. If not for the OOM handling behaviour of LogLine, it would always be equal to &iTempBuf
       
   139 	TUint iSyncWriteBufferBusy;
       
   140 	CPeriodic* iIdleWriteTimer;
       
   141 
       
   142 	// Log file
       
   143 	RFs iFs; // A couple of things assume the session path is always in the log directory on the c drive
       
   144 	RFile iLogFile;
       
   145 	CLogsDirWatcher* iLogsDirWatcher;
       
   146 	RPointerArray<MWriter> iWriters;
       
   147 	TFileName iFileBeingRotated; // This is used to temporarily store the name of a file while it's being rotated and possibly compressed
       
   148 	CSyncWriterWrapper* iCompressor;
       
   149 	RMessagePtr2 iRotationMessage; // To be completed when the log file compression finishes
       
   150 
       
   151 	// Settings
       
   152 	TUint iOptions; // TGlobalOptions
       
   153 	TBitFlags32 iFlags;
       
   154 	TInt iBufferSize;
       
   155 	TInt iNumBuffers;
       
   156 	TInt iNumRotates;
       
   157 	TUint iRotateBehaviour;
       
   158 	TInt64 iStartupTickInMicroseconds;
       
   159 	TTime iTimeAtStartup;
       
   160 	TInt iTickFreq;
       
   161 	// Tags
       
   162 	class TTagData
       
   163 		{
       
   164 	public:
       
   165 		TTagData(HBufC8* aName) : iTagName(aName), iRefCount(0), iEnabled(0), iThreadIdForRDebugger(0), iFlags() {}
       
   166 		void SetShouldDisplay() { iFlags.Set(EShouldDisplay); }
       
   167 		TBool ShouldDisplay() const { return iFlags.IsSet(EShouldDisplay); }
       
   168 
       
   169 		HBufC8* iTagName;
       
   170 		TInt iRefCount;
       
   171 		TUint32 iEnabled; // bitmask
       
   172 		TUint iThreadIdForRDebugger;
       
   173 	private:
       
   174 		enum TFlags {
       
   175 			EShouldDisplay, // Indicates this tag should be exposed to the client via GetTagStatesL
       
   176 			};
       
   177 		TBitFlags32 iFlags;
       
   178 		};
       
   179 
       
   180 	RPtrHashMap<TDesC8, TTagData> iTags; // Keys are the tag names, values are TTagDatas
       
   181 	RHashMap<TUint, TTagData*> iRDebugTags;
       
   182 	CDebugRouterClient* iKernDebugRouter;
       
   183 	TTagData* iRDebugTag; // Is always set. Only used in OOM conditions when we can't create a threadid&name tag
       
   184 	TTagData* iFallbackTag; // Always set. This tag represents the default enabled state for any new tags that appear while we're running
       
   185 	TTagData* iCloggerTag; // Always set. Used to figure out the internal logging mask (previously used iInternalLoggingMask)
       
   186 
       
   187 	CSessionWriterServer* iSessionWriterServer; // Support for the session writer
       
   188 	TInt iEnabledStatesSequenceNumber;
       
   189 	};
       
   190 
       
   191 #define MINTAGSTART "---------- --:--:--.---: [Clogger] " // Writers can use this too, if they want to
       
   192 
       
   193 class MSyncWriter
       
   194 	{
       
   195 public:
       
   196 	/*
       
   197 	 * Synchronously writes aBuf. Can leave to indicate failure (although the failure may well be ignored)
       
   198 	 */
       
   199 	virtual void WriteBufL(const TDesC8& aBuf) =0;
       
   200 	
       
   201 	/*
       
   202 	 * delete writer and all resources.
       
   203 	 */
       
   204 	virtual void CloseWriter() =0;
       
   205 	};
       
   206 
       
   207 class MWriter
       
   208 	{
       
   209 public:
       
   210 	/*
       
   211 	 * Start writing aBuf. The server guarantees not to call this if the plugin is not enabled (as defined by a call
       
   212 	 * to IsEnabled()) or if the plugin is already busy writing something else (as defined by IsBusyWriting()).
       
   213 	 * If the writer is enabled and not currently writing something else, but is unable to perform the write,
       
   214 	 * then it should call CompletedWritingBuf before returning, to indicate that the server shouldn't wait for it.
       
   215 	 *
       
   216 	 * All calls to WriteBuf must be matched by a call to CompletedWritingBuf.
       
   217 	 */
       
   218 	virtual void WriteBuf(TInt aBuf) =0;
       
   219 
       
   220 	virtual void CloseWriter() =0; // delete writer and all resources. Will never be called while a write is in progress.
       
   221 
       
   222 	/*
       
   223 	 * Enables complex writers to take action when they are disabled.
       
   224 	 * Writers must honour this setting by returning immediately when a write function is called when they are disabled.
       
   225 	 * This may be called when a write is in progess - if so the write of the current buffer should complete as normal, it
       
   226 	 * should just update its internal flag so that next time the server calls WriteBuf it returns immediately
       
   227 	 *
       
   228 	 * Generally though SetEnabled will simply update an iEnabled member variable
       
   229 	 *
       
   230 	 * Writers will get a call to SetEnabled after they are constructed, before WriteBuf is called for the first time.
       
   231 	 */
       
   232 	virtual void SetEnabled(TBool aEnabled) =0;
       
   233 	virtual TBool IsEnabled() =0;
       
   234 
       
   235 	virtual TBool IsBusyWriting() =0;
       
   236 	};
       
   237 
       
   238 class CLogWriter : public CActive, public MWriter
       
   239 	{
       
   240 public:
       
   241 	CLogWriter(CCloggerServer& aServer, RFile& aFile)
       
   242 		: CActive(EPriorityHigh), // It's more important to keep writing than to handle clientserver calls
       
   243 		iServer(aServer), iFile(aFile), iBuf(-1), iEnabled(EFalse)
       
   244 		{
       
   245 		CActiveScheduler::Add(this);
       
   246 		}
       
   247 
       
   248 	void WriteBuf(TInt aBuf);
       
   249 	void DoCancel();
       
   250 	void RunL();
       
   251 	void SetEnabled(TBool aEnabled);
       
   252 	TBool IsEnabled() { return iEnabled; }
       
   253 	void CloseWriter();
       
   254 	~CLogWriter();
       
   255 	TBool IsBusyWriting();
       
   256 		
       
   257 private:
       
   258 	CCloggerServer& iServer;
       
   259 	RFile& iFile;
       
   260 	TInt iBuf;
       
   261 	TBool iEnabled;
       
   262 	};
       
   263 
       
   264 class CRDebugWriter : public CBase, public MSyncWriter
       
   265 	{
       
   266 public:
       
   267 	CRDebugWriter(CCloggerServer& aServer);
       
   268 	void WriteBufL(const TDesC8& aBuf);
       
   269 	void CloseWriter();
       
   270 
       
   271 private:
       
   272 	CCloggerServer& iServer;
       
   273 	};
       
   274 
       
   275 class CMessageQueueWriter : public CBase, public MSyncWriter
       
   276 	{
       
   277 public:
       
   278 	static CMessageQueueWriter* NewL();	
       
   279 	void WriteBufL(const TDesC8& aBuf);
       
   280 	void CloseWriter();
       
   281 
       
   282 private:
       
   283 	CMessageQueueWriter();
       
   284 	~CMessageQueueWriter();
       
   285 
       
   286 private:
       
   287 	RMsgQueue<TBuf8<128> > iQ;
       
   288 	};
       
   289 
       
   290 class CSessionWriter : public CBase, public MWriter
       
   291 	{
       
   292 public:
       
   293 	CSessionWriter(CCloggerServer& aServer);
       
   294 	~CSessionWriter();
       
   295 
       
   296 	void WriteBuf(TInt aBuf);
       
   297 	void DoCancel();
       
   298 	void RunL();
       
   299 	void SetEnabled(TBool aEnabled);
       
   300 	TBool IsEnabled() { return iEnabled; }
       
   301 	void CloseWriter();
       
   302 	TBool IsBusyWriting();
       
   303 
       
   304 	void Completed();
       
   305 
       
   306 public:
       
   307 	CSessionWriterSession* iSession; // Support only one session
       
   308 
       
   309 private:
       
   310 	CCloggerServer& iServer;
       
   311 	TInt iBuf;
       
   312 	TBool iEnabled;
       
   313 	};
       
   314 
       
   315 class CSyncWriterWrapper : public CActive, public MWriter
       
   316 	{
       
   317 public:
       
   318 	static CSyncWriterWrapper* NewL(CCloggerServer& aServer, MSyncWriter& aWriter, TInt aWriterId); // Takes ownership of aWriter at end
       
   319 	void WriteBuf(TInt aBuf);
       
   320 	void DoCancel();
       
   321 	void RunL();
       
   322 	void SetEnabled(TBool aEnabled);
       
   323 	TBool IsEnabled() { return iEnabled; }
       
   324 	void CloseWriter();
       
   325 	~CSyncWriterWrapper();
       
   326 	TBool IsBusyWriting();
       
   327 
       
   328 private:
       
   329 	CSyncWriterWrapper(CCloggerServer& aServer, MSyncWriter& aWriter);
       
   330 	void ConstructL(TInt aWriterId);
       
   331 	static TInt ThreadFunction(TAny* aSelf);
       
   332 private:
       
   333 	CCloggerServer& iServer;
       
   334 	MSyncWriter& iWriter;
       
   335 	TInt iBuf;
       
   336 	TBool iEnabled;
       
   337 	RThread iMainThread;
       
   338 	RThread iWorkerThread;
       
   339 	TRequestStatus iThreadStatus;
       
   340 	TBool iOwnWriter; // Bit of a cludge to ensure ownership of aWriter is correct
       
   341 	};
       
   342 
       
   343 class CLogCompressor : public CBase, public MSyncWriter
       
   344 	{
       
   345 public:
       
   346 	static CLogCompressor* NewLC(CCloggerServer& aServer);
       
   347 	~CLogCompressor();
       
   348 	void WriteBufL(const TDesC8& aBuf);
       
   349 	void CloseWriter();
       
   350 
       
   351 private:
       
   352 	CLogCompressor(CCloggerServer& aServer);
       
   353 	void DoGzipL(RFile& aInput, const TDesC& aOutput);
       
   354 
       
   355 private:
       
   356 	CCloggerServer& iServer;
       
   357 	RFs iFs;
       
   358 	};
       
   359 
       
   360 class CDebugRouterClient : public CActive
       
   361 	{
       
   362 public:
       
   363 	static CDebugRouterClient* NewL(CCloggerServer& aServer);
       
   364 	~CDebugRouterClient();
       
   365 	void RunL();
       
   366 	void DoCancel();
       
   367 	void StartRouting(TBool aConsumeLogs);
       
   368 	void StopRouting();
       
   369 	void OpenChunkL();
       
   370 	TInt RegisterCrashDumpAreas(const TDesC8& aCrashDumpAreas);
       
   371 	TInt CreateKernChunkForClient(RThread* aClient, TInt aMaxSize, TInt aCommittedSize, RChunk& aOurChunk);
       
   372 	TInt AdjustChunk(RChunk& aChunk, TInt aNewSize);
       
   373 
       
   374 private:
       
   375 	CDebugRouterClient(CCloggerServer& aServer);
       
   376 	void ConstructL();
       
   377 
       
   378 private:
       
   379 	CCloggerServer& iServer;
       
   380 	RCloggerDebugRouter iDebugRouter;
       
   381 	RChunk iSharedChunk;
       
   382 	RBuf8 iTempBuf;
       
   383 	};
       
   384 
       
   385 #endif