From 6c701b58a24d96e37c323412f3d2aa334cd2ded1 Mon Sep 17 00:00:00 2001
From: Ludovic Pouzenc <ludovic@pouzenc.fr>
Date: Sun, 6 Mar 2011 20:46:29 +0000
Subject: La gestion minimaliste des évènements de modification des slices est
 faite. Un dump à chaque event a été codé dans le main pour tester cet aspect.
 C'est ok. Go go go ncurses :D
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

git-svn-id: file:///var/svn/2011-ddhardrescue/trunk@11 d3078510-dda0-49f1-841c-895ef4b7ec81
---
 src/ddhardrescue.c | 32 +++++++++++++++++++-------------
 src/recover.c      | 19 ++++++++++---------
 src/slices.c       |  2 +-
 src/slices_evt.c   | 22 ++++++++++++++++++++++
 4 files changed, 52 insertions(+), 23 deletions(-)
 create mode 100644 src/slices_evt.c

(limited to 'src')

diff --git a/src/ddhardrescue.c b/src/ddhardrescue.c
index afad903..9f355b3 100755
--- a/src/ddhardrescue.c
+++ b/src/ddhardrescue.c
@@ -5,7 +5,7 @@
 #include <string.h>
 #include <pthread.h>
  
-#include "slices.h"
+#include "slices_evt.h"
 #include "recover.h"
 #include "utils.h"
 
@@ -14,17 +14,9 @@ int end=0;
 //FIXME remove me, only for tests
 unsigned long c=0;
 
-typedef enum { E_BOUND, E_TYPE } sliceEventKind_t;
-
-typedef struct {
-	slices_t *data;
-	pthread_mutex_t mutex;
-	void (*slices_listener)(sliceEventKind_t eventKind, slices_t *slices, slice_t *slice);
-} slices_manage_t;
-
 struct threadArgs {
 	struct progArgs *progArgs;
-	slices_manage_t *slices;
+	slices_evt_t *slices;
 };
 
 
@@ -32,6 +24,16 @@ void sigHookAbrt() {
 	end=1;
 }
 
+//TODO : remove that when procViewer is done
+void dumper(slices_evt_t *slicesEvt, slice_t *modifiedSlice) {
+	address_t blockSize=0;
+	char *dump;
+	dump=slicesDump(slicesEvt->data, &blockSize, 1000, 0, 21474836480ULL);
+	puts(dump);
+	free(dump);
+
+}
+
 void *procWorker(void *a);
 void *procViewer(void *a);
 
@@ -41,7 +43,7 @@ int main(int argc, char **argv) {
 	pthread_t tWorker, tViewer;
 
 	// Main data structures
-	slices_manage_t slices;
+	slices_evt_t slices;
 
 	// Progam and threads arguments
 	struct progArgs args;
@@ -72,6 +74,7 @@ int main(int argc, char **argv) {
 	// Data structure initialization
 	memset(&slices, 0, sizeof(slices));
 	slices.data=slicesNewSingleton(args.beginSector, args.endSector, S_UNKNOWN);
+	slices.eventListener=dumper;
 	res=pthread_mutex_init(&(slices.mutex), NULL);
 	if (res!=0) {
 		return 3;
@@ -96,7 +99,7 @@ int main(int argc, char **argv) {
 	(void) pthread_join(tWorker, NULL);
 	(void) pthread_join(tViewer, NULL);
 
-	//Final dump of datas	
+	/*Final dump of datas	
 	address_t blockSize=0;
 	char *dump;
 	dump=slicesDump(slices.data, &blockSize, 1000, args.beginSector, args.endSector);
@@ -104,6 +107,7 @@ int main(int argc, char **argv) {
 	free(dump);
 	printf("blockSize==%lld\n", blockSize);
 	printf("slices->count==%d\n", slices.data->count);
+	*/
 
 	//Resources desallocation
 	(void) pthread_mutex_destroy(&(slices.mutex));
@@ -125,7 +129,7 @@ void * procWorker(void *a) {
 	struct threadArgs *tArgs = (struct threadArgs *)a;
 
 	recover(
-		tArgs->slices->data,
+		tArgs->slices,
 		tArgs->progArgs->src,
 		tArgs->progArgs->dst,
 		tArgs->progArgs->ddOpts
@@ -138,3 +142,5 @@ void *procViewer(void *a) {
 
 	return a;
 }
+
+
diff --git a/src/recover.c b/src/recover.c
index 309ebfb..b4f0da7 100755
--- a/src/recover.c
+++ b/src/recover.c
@@ -5,12 +5,12 @@
 
 extern unsigned long c;
 
-void recover(slices_t *slices, char *src, char *dst, char *ddOpts) {
+void recover(slices_evt_t *slicesEvt, char *src, char *dst, char *ddOpts) {
 	slice_t *sliceToRead;
 	address_t firstError=0, median, foundMax=0;
 	int res;
 
-	sliceToRead=slices->first;
+	sliceToRead=slicesEvt->data->first;
 	while (!end) { 
 		// try to recover sliceToRead and split it if read error
 		switch ( tryRecoverUntilError(sliceToRead, &firstError, src, dst, ddOpts) ) {
@@ -20,7 +20,7 @@ void recover(slices_t *slices, char *src, char *dst, char *ddOpts) {
 				break;
 			case EIO:
 				// slice recovery has encountered a readerror
-				res=sliceSplit(slices, sliceToRead, firstError, S_RECOVERED, S_UNREADABLE, S_UNKNOWN);
+				res=sliceSplitEvt(slicesEvt, sliceToRead, firstError, S_RECOVERED, S_UNREADABLE, S_UNKNOWN);
 				if (res<1) {
 					//TODO
 					printf("sliceSplit return %d\n", res);
@@ -34,7 +34,7 @@ void recover(slices_t *slices, char *src, char *dst, char *ddOpts) {
 		/* Now, search the largest S_UNKNOWN zone
 		 split it in two parts */
 		//sliceToRead=slicesFindLargest(slices, S_UNKNOWN);
-		sliceToRead=slicesFindLargestFast(slices, &foundMax, S_UNKNOWN, foundMax, sliceToRead->next);
+		sliceToRead=slicesFindLargestFast(slicesEvt->data, &foundMax, S_UNKNOWN, foundMax, sliceToRead->next);
 		if ( sliceToRead == NULL ) {
 			// There is nothing more to recover, bailout
 			end=1;
@@ -43,7 +43,7 @@ void recover(slices_t *slices, char *src, char *dst, char *ddOpts) {
 			
 
  		median=(sliceToRead->begin+sliceToRead->end)/2;
-		res=sliceSplit(slices, sliceToRead, median, S_UNKNOWN, S_UNKNOWN, S_UNKNOWN);
+		res=sliceSplitEvt(slicesEvt, sliceToRead, median, S_UNKNOWN, S_UNKNOWN, S_UNKNOWN);
 		switch (res) {
 			case 1:
 				// No split, try analyse this zone
@@ -92,10 +92,11 @@ int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError, char *src,
 	*firstError=sliceToRead->begin;
 	res=EIO;
 */
+/*
 	// Simulate that we have systematically a read error at last sector
 	*firstError=sliceToRead->end;
 	res=EIO;
-
+*/
 /*
 	// Simulate that we have systematically a read error at first sector
 	// Simulate for each read, tha we have an error just in the middle if read for mor than one sector
@@ -106,16 +107,16 @@ int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError, char *src,
 		res=EIO;
 	}
 */
-/*
+
 	// Simulate for each read a pseudo random error position and generate some cases of full read without error
-	int error=sliceToRead->begin + rand()%count;
+	address_t error=sliceToRead->begin + rand()%count;
 	if ( error % 42 == 0 ) {
 		res=0;
 	} else {
 		res=EIO;
 		*firstError=error;
 	}
-*/
+
 
 	return res;
 }
diff --git a/src/slices.c b/src/slices.c
index 9f40b9e..21fdd3b 100755
--- a/src/slices.c
+++ b/src/slices.c
@@ -36,7 +36,7 @@ int sliceSplit(slices_t *slices, slice_t *initialSlice, address_t splitAt, slice
 	and then between he first and second if needed.
 	*/
 
-	if ( splitAt < initialSlice->begin || splitAt > initialSlice->end ) return 2;
+	if ( splitAt < initialSlice->begin || splitAt > initialSlice->end ) return -2;
 	
 	// Test before act because we'll change values of the initialSlice because
 	//  it would become the firstSlice or even the second one if the first is zero-lenght
diff --git a/src/slices_evt.c b/src/slices_evt.c
new file mode 100644
index 0000000..43cb568
--- /dev/null
+++ b/src/slices_evt.c
@@ -0,0 +1,22 @@
+#include "slices_evt.h"
+
+int sliceSplitEvt(slices_evt_t *slicesEvt, slice_t *initialSlice, address_t splitAt, sliceStatus_t statusBefore, sliceStatus_t statusAt, sliceStatus_t statusAfter) {
+	int res;
+	res=sliceSplit(slicesEvt->data, initialSlice, splitAt, statusBefore, statusAt, statusAfter);
+	if ( slicesEvt->eventListener != NULL ) {
+		//FIXME : this could be dereference a NULL pointer. Implement a real listener system with a thread-safe FIFO
+		switch(res) {
+			case 3:
+				slicesEvt->eventListener(slicesEvt, initialSlice->next->next);
+			case 2:
+				slicesEvt->eventListener(slicesEvt, initialSlice->next);
+			case 1:
+				slicesEvt->eventListener(slicesEvt, initialSlice);
+				break;
+			default:
+				// No events on split errors
+				break;
+		}
+	}
+	return res;
+}
-- 
cgit v1.2.3