1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
4  *                         University Research and Technology
5  *                         Corporation.  All rights reserved.
6  * Copyright (c) 2004-2005 The University of Tennessee and The University
7  *                         of Tennessee Research Foundation.  All rights
8  *                         reserved.
9  * Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
10  *                         University of Stuttgart.  All rights reserved.
11  * Copyright (c) 2004-2005 The Regents of the University of California.
12  *                         All rights reserved.
13  * Copyright (c) 2013      Cisco Systems, Inc.  All rights reserved.
14  * Copyright (c) 2013      Los Alamos National Security, LLC.  All rights
15  *                         reserved.
16  * Copyright (c) 2015      Research Organization for Information Science
17  *                         and Technology (RIST). All rights reserved.
18  * Copyright (c) 2016      University of Houston. All rights reserved.
19  * Copyright (c) 2017      IBM Corporation. All rights reserved.
20  * $COPYRIGHT$
21  *
22  * Additional copyrights may follow
23  *
24  * $HEADER$
25  */
26 
27 #include "ompi_config.h"
28 
29 #include "ompi/mpi/c/bindings.h"
30 #include "ompi/runtime/params.h"
31 #include "ompi/communicator/communicator.h"
32 #include "ompi/errhandler/errhandler.h"
33 #include "ompi/info/info.h"
34 #include "ompi/file/file.h"
35 #include "ompi/mca/io/io.h"
36 #include "ompi/mca/io/base/base.h"
37 #include "ompi/memchecker.h"
38 
39 
40 extern opal_mutex_t ompi_mpi_file_bootstrap_mutex;
41 
42 #if OMPI_BUILD_MPI_PROFILING
43 #if OPAL_HAVE_WEAK_SYMBOLS
44 #pragma weak MPI_File_open = PMPI_File_open
45 #endif
46 #define MPI_File_open PMPI_File_open
47 #endif
48 
49 static const char FUNC_NAME[] = "MPI_File_open";
50 
51 
MPI_File_open(MPI_Comm comm,const char * filename,int amode,MPI_Info info,MPI_File * fh)52 int MPI_File_open(MPI_Comm comm, const char *filename, int amode,
53                   MPI_Info info, MPI_File *fh)
54 {
55     int rc;
56 
57     MEMCHECKER(
58         memchecker_comm(comm);
59     );
60 
61     if (MPI_PARAM_CHECK) {
62         OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
63         if (NULL == info || ompi_info_is_freed(info)) {
64             return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INFO,
65                                           FUNC_NAME);
66         } else if (ompi_comm_invalid(comm)) {
67             return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM,
68                                           FUNC_NAME);
69         }
70         if (OMPI_COMM_IS_INTER(comm)) {
71             return OMPI_ERRHANDLER_INVOKE (comm, MPI_ERR_COMM,
72                                           FUNC_NAME);
73         }
74 
75     }
76 
77     /* Note that MPI-2:9.7 (p265 in the ps; p261 in the pdf) says that
78        errors in MPI_FILE_OPEN (before the file handle is created)
79        should invoke the default error handler on MPI_FILE_NULL.
80        Hence, if we get a file handle out of ompi_file_open(), invoke
81        the error handler on that.  If not, invoke the error handler on
82        MPI_FILE_NULL. */
83 
84     /* The io framework is only initialized lazily.  If it hasn't
85        already been initialized, do so now (note that MPI_FILE_OPEN
86        and MPI_FILE_DELETE are the only two places that it will be
87        initialized). */
88 
89     /* For multi-threaded scenarios, initializing the file i/o
90        framework and mca infrastructure needs to be protected
91        by a mutex, similarly to the other frameworks in
92        ompi/runtime/ompi_mpi_init.c
93     */
94 
95     opal_mutex_lock(&ompi_mpi_file_bootstrap_mutex);
96 
97     rc = mca_base_framework_open(&ompi_io_base_framework, 0);
98     if (OMPI_SUCCESS != rc) {
99         opal_mutex_unlock(&ompi_mpi_file_bootstrap_mutex);
100         return OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, rc, FUNC_NAME);
101     }
102     opal_mutex_unlock(&ompi_mpi_file_bootstrap_mutex);
103 
104     OPAL_CR_ENTER_LIBRARY();
105 
106     /* Create an empty MPI_File handle */
107 
108     *fh = MPI_FILE_NULL;
109     rc = ompi_file_open(comm, filename, amode, &(info->super), fh);
110 
111     /* Creating the file handle also selects a component to use,
112        creates a module, and calls file_open() on the module.  So
113        we're good to go. */
114     OMPI_ERRHANDLER_RETURN(rc, *fh, rc, FUNC_NAME);
115 }
116