There is some information about this problem in the Action Reference for save post:
If you are calling a function such as wp_update_post that includes the save_post hook, your hooked function will create an infinite loop. To avoid this, unhook your function before calling the function you need, then re-hook it afterward.
So something like this should work:
[...]
add_action( 'save_post', array( $this, 'save_meta_box' ), 13, 2 );
[...]
public function save_meta_box( $post_id, $post ) {
if ( isset( $_POST['options'] ) ) {
myplugin_set_options( $post_id, $_POST['options'] );
remove_action( 'save_post', array( $this, 'save_meta_box' ), 13, 2 );
// switch post visibility
switch ( $_POST['options']['type'] ) {
case 'normal':
wp_update_post( array( 'ID' => $post_id, 'post_status' => 'private' ));
break;
case 'extended':
wp_update_post( array( 'ID' => $post_id, 'post_status' => 'publish' ));
break;
}
add_action( 'save_post', array( $this, 'save_meta_box' ), 13, 2 );
}
}