Index: wp-includes/widgets.php
===================================================================
--- wp-includes/widgets.php	(revision 23297)
+++ wp-includes/widgets.php	(working copy)
@@ -901,6 +901,10 @@
 		do_action( 'dynamic_sidebar', $wp_registered_widgets[$id] );
 
 		if ( is_callable($callback) ) {
+
+			if ( wp_check_widget_lock( $id ) )
+				_admin_notice_widget_locked( $wp_registered_widgets[$id] );
+
 			call_user_func_array($callback, $params);
 			$did_one = true;
 		}
@@ -1268,3 +1272,106 @@
 
 	return $sidebars_widgets;
 }
+
+/**
+ * Check to see if the post is currently being edited by another user.
+ *
+ * @since 3.6.0
+ *
+ * @param int $id Widget id
+ * @return bool|int False: not locked or locked by current user. Int: user ID of user with lock.
+ */
+function wp_check_widget_lock( $id ) {
+	$locks = get_option( '_widgets_lock' );
+	if ( empty( $locks[$id] ) )
+		return;
+
+	$lasts = get_option( '_widgets_last' );
+	$last = $lasts[$id];
+
+	$lock = explode( ':', $locks[$id] );
+	$time = $lock[0];
+	$user = isset( $lock[1] ) ? $lock[1] : $last;
+
+	$time_window = apply_filters( 'wp_check_widget_lock_window', AUTOSAVE_INTERVAL * 2 );
+
+	if ( $time && $time > time() - $time_window && $user != get_current_user_id() )
+		return $user;
+
+	return false;
+}
+
+/**
+ * Mark the widget as currently being edited by the current user
+ *
+ * @since 3.6.0
+ *
+ * @param int $id ID of the widget to be locked
+ * @return bool|array Returns false if there is no current user, or an array of the lock time and the user ID.
+ */
+function wp_set_widget_lock( $id ) {
+	if ( 0 == ( $user_id = get_current_user_id() ) )
+		return false;
+
+	$now = time();
+	$lock = "$now:$user_id";
+
+	$locks = get_option( '_widgets_lock' );
+	$locks[$id] = $lock;
+
+	update_option( '_widgets_lock', $locks );
+	return array( $now, $user_id );
+}
+
+/**
+ * Mark the widget's last editor as the current user
+ *
+ * @since 3.6.0
+ *
+ * @param string $id ID of the widget to being edited
+ * @return bool|array Returns false if is no current user
+ */
+function wp_set_widget_last( $id ) {
+	if ( 0 == ( $user_id = get_current_user_id() ) )
+		return;
+
+	$lasts = get_option( '_widget_lasts' );
+
+	if ( ! empty( $lasts[$id] ) && $lasts[$id] == get_current_user_id() )
+		return $lasts[$id];
+
+	$lasts[$id] = $user_id;
+	update_option( '_widget_lasts', $lasts );
+
+	return $user_id;
+}
+
+/**
+ * Outputs the notice message to say that someone else is editing this post at the moment.
+ *
+ * @since 3.6.0
+ * @return none
+ */
+function _admin_notice_widget_locked( $widget ) {
+	$locks = get_option( '_widgets_lock' );
+	$lasts = get_option( '_widgets_last' );
+
+	$last = 0;
+	if ( ! empty( $lasts ) )
+		$last = $lasts[$widget['id']];
+
+	$lock = explode( ':', $locks[$widget['id']] );
+	$user = isset( $lock[1] ) ? $lock[1] : $last;
+	if ( ! empty( $user ) ) {
+		$last_user = get_userdata( $user );
+		$last_user_name = $last_user->display_name;
+	} else {
+		$last_user_name = __( 'Somebody' );
+	}
+
+	$message = sprintf( __( 'Warning: %s is currently editing the <strong>%s</strong> widget.' ),
+		esc_html( $last_user_name ),
+		esc_html( $widget['name'] )
+	);
+	printf( '<div class="widget-error" data-id="%s"><p>%s</p></div>', $widget['id'], $message );
+}
\ No newline at end of file
Index: wp-admin/includes/ajax-actions.php
===================================================================
--- wp-admin/includes/ajax-actions.php	(revision 23297)
+++ wp-admin/includes/ajax-actions.php	(working copy)
@@ -1566,6 +1566,9 @@
 		}
 	}
 
+	wp_set_widget_lock( $widget_id );
+	wp_set_widget_last( $widget_id );
+
 	if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
 		$sidebars[$sidebar_id] = $sidebar;
 		wp_set_sidebars_widgets($sidebars);
Index: wp-admin/js/widgets.js
===================================================================
--- wp-admin/js/widgets.js	(revision 23297)
+++ wp-admin/js/widgets.js	(working copy)
@@ -103,6 +103,8 @@
 				ui.item.css({margin:'', 'width':''});
 			},
 			stop: function(e,ui) {
+				wpWidgets.fixErrors(ui.item.parent());
+
 				if ( ui.item.hasClass('ui-draggable') && ui.item.data('draggable') )
 					ui.item.draggable('destroy');
 
@@ -174,6 +176,17 @@
 		});
 	},
 
+	fixErrors : function (sb, del) {
+		sb.find('div.widget-error').hide().each(function (i, error) {
+			error = $(error);
+
+			var node = error.clone(), wdgt = error.parent().find('[id$="' + error.data('id') + '"]');
+			if ( error.remove() && wdgt.length && ( !del || ( del.prop('id') != wdgt.prop('id') ) ) )
+				wdgt.before(node.show());
+
+		});
+	},
+
 	saveOrder : function(sb) {
 		if ( sb )
 			$('#' + sb).closest('div.widgets-holder-wrap').find('.spinner').css('display', 'inline-block');
@@ -197,7 +210,9 @@
 	},
 
 	save : function(widget, del, animate, order) {
-		var sb = widget.closest('div.widgets-sortables').attr('id'), data = widget.find('form').serialize(), a;
+		var sortables = widget.closest('div.widgets-sortables'),
+		sb = sortables.attr('id'),
+		data = widget.find('form').serialize(), a;
 		widget = $(widget);
 		$('.spinner', widget).show();
 
@@ -234,6 +249,8 @@
 					widget.remove();
 					wpWidgets.resize();
 				}
+
+				wpWidgets.fixErrors(sortables, widget);
 			} else {
 				$('.spinner').hide();
 				if ( r && r.length > 2 ) {
@@ -241,6 +258,7 @@
 					wpWidgets.appendTitle(widget);
 					wpWidgets.fixLabels(widget);
 				}
+				wpWidgets.fixErrors(sortables);
 			}
 			if ( order )
 				wpWidgets.saveOrder();
Index: wp-admin/css/colors-fresh.css
===================================================================
--- wp-admin/css/colors-fresh.css	(revision 23297)
+++ wp-admin/css/colors-fresh.css	(working copy)
@@ -275,12 +275,14 @@
 }
 
 div.error,
+div.widget-error,
 .login #login_error {
 	background-color: #ffebe8;
 	border-color: #c00;
 }
 
-div.error a {
+div.error a,
+div.widget-error a {
 	color: #c00;
 }
 
Index: wp-admin/css/wp-admin.css
===================================================================
--- wp-admin/css/wp-admin.css	(revision 23297)
+++ wp-admin/css/wp-admin.css	(working copy)
@@ -498,6 +498,7 @@
 .widefat,
 div.updated,
 div.error,
+div.widget-error,
 .wrap .add-new-h2,
 textarea,
 input[type="text"],
@@ -651,13 +652,15 @@
 }
 
 div.updated,
-div.error {
+div.error,
+div.widget-error {
 	padding: 0 0.6em;
 	margin: 5px 15px 2px;
 }
 
 div.updated p,
-div.error p {
+div.error p,
+div.widget-error p {
 	margin: 0.5em 0;
 	padding: 2px;
 }
@@ -8071,6 +8074,10 @@
 	padding: 15px 0 0;
 }
 
+div.widget-error {
+	margin-bottom: 15px;
+}
+
 #available-widgets .widget-holder {
 	padding: 7px 5px 0;
 }
