diff --git a/app.c b/app.c
index 13040d585634a0249c91bd548fa854bdaf8c343a..da7e71f750ba42f25f5c34db1a7d40bfccf8fcb6 100755
--- a/app.c
+++ b/app.c
@@ -497,7 +497,7 @@ int ast_play_and_wait(struct ast_channel *chan, const char *fn)
 static int global_silence_threshold = 128;
 static int global_maxsilence = 0;
 
-int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence)
+int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path)
 {
 	char d, *fmts;
 	char comment[256];
@@ -507,7 +507,7 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
 	char *sfmt[MAX_OTHER_FORMATS];
 	char *stringp=NULL;
 	time_t start, end;
-	struct ast_dsp *sildet;   	/* silence detector dsp */
+	struct ast_dsp *sildet=NULL;   	/* silence detector dsp */
 	int totalsilence = 0;
 	int dspsilence = 0;
 	int gotsilence = 0;		/* did we timeout for silence? */
@@ -564,18 +564,23 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
 		}
 	}
 
-	sildet = ast_dsp_new(); /* Create the silence detector */
-	if (!sildet) {
-		ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
-		return -1;
-	}
-	ast_dsp_set_threshold(sildet, silencethreshold);
+	if (path)
+		ast_unlock_path(path);
+
+
 	
 	if (maxsilence > 0) {
+		sildet = ast_dsp_new(); /* Create the silence detector */
+		if (!sildet) {
+			ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
+			return -1;
+		}
+		ast_dsp_set_threshold(sildet, silencethreshold);
 		rfmt = chan->readformat;
 		res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
+			ast_dsp_free(sildet);
 			return -1;
 		}
 	}
@@ -619,13 +624,13 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
 						totalsilence = 0;
 
 					if (totalsilence > maxsilence) {
-					/* Ended happily with silence */
-                                        if (option_verbose > 2)
-                                                ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
-					ast_frfree(f);
-					gotsilence = 1;
-					outmsg=2;
-					break;
+						/* Ended happily with silence */
+						if (option_verbose > 2)
+							ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
+						ast_frfree(f);
+						gotsilence = 1;
+						outmsg=2;
+						break;
 					}
 				}
 				/* Exit on any error */
@@ -704,6 +709,8 @@ int ast_play_and_record(struct ast_channel *chan, const char *playfile, const ch
 		if(!ast_streamfile(chan, "auth-thankyou", chan->language))
 			ast_waitstream(chan, "");
 	}
+	if (sildet)
+		ast_dsp_free(sildet);
 	return res;
 }
 
@@ -1061,7 +1068,50 @@ int ast_seperate_app_args(char *buf, char delim, char **array, int arraylen)
 	return x;
 }
 
-int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration) 
+int ast_lock_path(const char *path)
+{
+	char *s;
+	char *fs;
+	int res;
+	int fd;
+	time_t start;
+	s = alloca(strlen(path) + 10);
+	fs = alloca(strlen(path) + 20);
+	if (!fs || !s) {
+		ast_log(LOG_WARNING, "Out of memory!\n");
+		return -1;
+	}
+	snprintf(fs, strlen(path) + 19, "%s/%s-%08x", path, ".lock", rand());
+	fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, 0600);
+	if (fd < 0) {
+		fprintf(stderr, "Unable to create lock file: %s\n", strerror(errno));
+		return -1;
+	}
+	close(fd);
+	snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock");
+	time(&start);
+	while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5))
+		usleep(1);
+	if (res < 0) {
+		ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno));
+	}
+	unlink(fs);
+	ast_log(LOG_DEBUG, "Locked path '%s'\n", path);
+	return res;
+}
+
+int ast_unlock_path(const char *path)
+{
+	char *s;
+	s = alloca(strlen(path) + 10);
+	if (!s)
+		return -1;
+	snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock");
+	ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path);
+	return unlink(s);
+}
+
+int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path) 
 {
 	int silencethreshold = 128; 
 	int maxsilence=0;
@@ -1108,7 +1158,7 @@ int ast_record_review(struct ast_channel *chan, const char *playfile, const char
 			else	
 				ast_verbose(VERBOSE_PREFIX_3 "Recording\n");
 			recorded = 1;
-			cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence);
+			cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path);
 			if (cmd == -1) {
 			/* User has hung up, no options to give */
 				return cmd;
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index e53c8bb65821cc0c229dbf04d95e41530cead165..9385269f6c9dd5d6a27ee2af775beaf44ec24d8f 100755
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -626,7 +626,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
         snprintf(user->namerecloc,sizeof(user->namerecloc),"%s/meetme-username-%s-%d",AST_SPOOL_DIR,conf->confno,user->user_no);
 
 	if (!(confflags & CONFFLAG_QUIET) && (confflags & CONFFLAG_INTROUSER))
-		ast_record_review(chan,"vm-rec-name",user->namerecloc, 10,"sln", &duration);
+		ast_record_review(chan,"vm-rec-name",user->namerecloc, 10,"sln", &duration, NULL);
 
 	while((confflags & CONFFLAG_WAITMARKED) && (conf->markedusers == 0)) {
 		confflags &= ~CONFFLAG_QUIET;
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 3487bdd4f3bbc8ecdb402e24d07c9630e3231e70..70d0e2b00c746682db4bc25eba43172ea310bcf8 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -185,7 +185,7 @@ struct vm_state {
 };
 static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option);
 static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context);
-static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration);
+static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir);
 static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc);
 static int vm_play_folder_name(struct ast_channel *chan, char *mbox);
 
@@ -1299,11 +1299,13 @@ static int last_message_index(char *dir)
 {
 	int x;
 	char fn[256];
+	ast_lock_path(dir);
 	for (x=0;x<MAXMSG;x++) {
 		make_file(fn, sizeof(fn), dir, x);
 		if (ast_fileexists(fn, NULL, NULL) < 1)
 			break;
 	}
+	ast_unlock_path(dir);
 	return x-1;
 }
 
@@ -1934,6 +1936,7 @@ static void copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int
 
 	make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
 	make_file(frompath, sizeof(frompath), fromdir, msgnum);
+	ast_lock_path(topath);
 	recipmsgnum = 0;
 	do {
 		make_file(topath, sizeof(topath), todir, recipmsgnum);
@@ -1946,7 +1949,7 @@ static void copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int
 	} else {
 		ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
 	}
-
+	ast_unlock_path(topath);
 	notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
 }
 
@@ -2132,18 +2135,19 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
 		strncpy(fmt, vmfmts, sizeof(fmt) - 1);
 		if (!ast_strlen_zero(fmt)) {
 			msgnum = 0;
-			do {
-				make_file(fn, sizeof(fn), dir, msgnum);
-				if (!EXISTS(dir,msgnum,fn,chan->language))
-					break;
-				msgnum++;
-			} while (msgnum < MAXMSG);
 			if (res >= 0) {
 				/* Unless we're *really* silent, try to send the beep */
 				res = ast_streamfile(chan, "beep", chan->language);
 				if (!res)
 					res = ast_waitstream(chan, "");
 			}
+			ast_lock_path(dir);
+			do {
+				make_file(fn, sizeof(fn), dir, msgnum);
+				if (!EXISTS(dir,msgnum,fn,chan->language))
+					break;
+				msgnum++;
+			} while (msgnum < MAXMSG);
 			if (msgnum < MAXMSG) {
 				/* Store information */
 				snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
@@ -2177,7 +2181,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
 					fclose(txt);
 				} else
 					ast_log(LOG_WARNING, "Error opening text file for output\n");
-				res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration);
+				res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration, dir);
 				if (res == '0')
 					goto transfer;
 				if (res > 0)
@@ -2220,6 +2224,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
 					DISPOSE(dir, msgnum);
 				}
 			} else {
+				ast_unlock_path(dir);
 				res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
 				if (!res)
 					res = ast_waitstream(chan, "");
@@ -2248,6 +2253,7 @@ static void resequence_mailbox(char * dir)
 	char sfn[256];
 	char dfn[256];
 
+	ast_lock_path(dir);
 	for (x=0,dest=0;x<MAXMSG;x++) {
 		make_file(sfn, sizeof(sfn), dir, x);
 		if (EXISTS(dir, x, sfn, NULL)) {
@@ -2260,6 +2266,7 @@ static void resequence_mailbox(char * dir)
 			dest++;
 		}
 	}
+	ast_unlock_path(dir);
 }
 
 
@@ -2280,16 +2287,20 @@ static int save_to_folder(char *dir, int msg, char *context, char *username, int
 	make_file(sfn, sizeof(sfn), dir, msg);
 	make_dir(ddir, sizeof(ddir), context, username, dbox);
 	mkdir(ddir, 0700);
+	ast_lock_path(ddir);
 	for (x=0;x<MAXMSG;x++) {
 		make_file(dfn, sizeof(dfn), ddir, x);
 		if (!EXISTS(ddir, x, dfn, NULL))
 			break;
 	}
-	if (x >= MAXMSG)
+	if (x >= MAXMSG) {
+		ast_unlock_path(ddir);
 		return -1;
+	}
 	if (strcmp(sfn, dfn)) {
 		COPY(dir, msg, ddir, x, sfn, dfn);
 	}
+	ast_unlock_path(ddir);
 	return 0;
 }
 
@@ -3403,6 +3414,7 @@ static void close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
 	int x;
 	if (vms->lastmsg > -1) { 
 		/* Get the deleted messages fixed */ 
+		ast_lock_path(vms->curdir);
 		vms->curmsg = -1; 
 		for (x=0;x < MAXMSG;x++) { 
 			if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
@@ -3426,6 +3438,7 @@ static void close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
 				break;
 			DELETE(vms->curdir, x, vms->fn);
 		} 
+		ast_unlock_path(vms->curdir);
 	} 
 	memset(vms->deleted, 0, sizeof(vms->deleted)); 
 	memset(vms->heard, 0, sizeof(vms->heard)); 
@@ -4067,7 +4080,7 @@ static int vm_newuser(struct ast_channel *chan, struct ast_vm_user *vmu, struct
 	/* If forcename is set, have the user record their name */	
 	if (ast_test_flag(vmu, VM_FORCENAME)) {
 		snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
-		cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration);
+		cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
 		if (cmd < 0 || cmd == 't' || cmd == '#')
 			return cmd;
 	}
@@ -4075,11 +4088,11 @@ static int vm_newuser(struct ast_channel *chan, struct ast_vm_user *vmu, struct
 	/* If forcegreetings is set, have the user record their greetings */
 	if (ast_test_flag(vmu, VM_FORCEGREET)) {
 		snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
-		cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration);
+		cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
 		if (cmd < 0 || cmd == 't' || cmd == '#')
 			return cmd;
 		snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
-		cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration);
+		cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
 		if (cmd < 0 || cmd == 't' || cmd == '#')
 			return cmd;
 	}
@@ -4113,15 +4126,15 @@ static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct
 		switch (cmd) {
 		case '1':
 			snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
-			cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration);
+			cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
 			break;
 		case '2': 
 			snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
-			cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration);
+			cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
 			break;
 		case '3': 
 			snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
-			cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration);
+			cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
 			break;
 		case '4': 
 			cmd = vm_tempgreeting(chan, vmu, vms, fmtc);
@@ -4209,7 +4222,7 @@ static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, st
 		if (ast_fileexists(prefile, NULL, NULL) > 0) {
 			switch (cmd) {
 			case '1':
-				cmd = play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration);
+				cmd = play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
 				break;
 			case '2':
 				ast_filedelete(prefile, NULL);
@@ -4233,7 +4246,7 @@ static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, st
 				}
 			}
 		} else {
-			play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration);
+			play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
 			cmd = 't';	
 		}
 	}
@@ -4908,7 +4921,8 @@ static int append_mailbox(char *context, char *mbox, char *data)
 	return 0;
 }
 
-static int vm_box_exists(struct ast_channel *chan, void *data) {
+static int vm_box_exists(struct ast_channel *chan, void *data) 
+{
 	struct localuser *u;
 	struct ast_vm_user svm;
 	char *context, *box;
@@ -5738,7 +5752,7 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s
 
  
  
-static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration)
+static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir)
 {
 	/* Record message & let caller review or re-record it, or set options if applicable */
  	int res = 0;
@@ -5793,7 +5807,7 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
  			}
  			recorded = 1;
  			/* After an attempt has been made to record message, we have to take care of INTRO and beep for incoming messages, but not for greetings */
-			cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence);
+			cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir);
  			if (cmd == -1) {
  			/* User has hung up, no options to give */
  				return cmd;
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
index ff7fcb6ea67b776c1d0b7b47cd60e9e35ee20949..c3c3558544ffcf326dd47ec0395dad156858d5c2 100755
--- a/include/asterisk/app.h
+++ b/include/asterisk/app.h
@@ -66,13 +66,20 @@ int ast_control_streamfile(struct ast_channel *chan, const char *file, const cha
 int ast_play_and_wait(struct ast_channel *chan, const char *fn);
 
 /*! Record a file for a max amount of time (in seconds), in a given list of formats separated by '|', outputting the duration of the recording, and with a maximum */
-/*   permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults. */
-int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms);
+/*   permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults. 
+     calls ast_unlock_path() on 'path' if passed */
+int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path);
 
 /*! Record a message and prepend the message to the given record file after playing the optional playfile (or a beep), storing the duration in 'duration' and with a maximum */
 /*   permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults. */
 int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime_sec, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence_ms);
 
+/* Lock a path */
+int ast_lock_path(const char *path);
+
+/* Unlock a path */
+int ast_unlock_path(const char *path);
+
 #define GROUP_CATEGORY_PREFIX "GROUP"
 
 /*! Split a group string into group and category, returning a default category if none is provided. */
@@ -94,7 +101,7 @@ int ast_seperate_app_args(char *buf, char delim, char **array, int arraylen);
 int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout);
 
 /*! Allow to record message and have a review option */
-int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration);
+int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }