1
/****************************************************************************
2
**
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the QtCore module of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#include "qsystemsemaphore.h"
43
#include "qsystemsemaphore_p.h"
44
#include "qcoreapplication.h"
45
#include <qdebug.h>
46
47
#include "qcore_symbian_p.h"
48
#include <e32cmn.h>
49
50
#ifndef QT_NO_SYSTEMSEMAPHORE
51
52
//#define QSYSTEMSEMAPHORE_DEBUG
53
54
QT_BEGIN_NAMESPACE
55
56
QSystemSemaphorePrivate::QSystemSemaphorePrivate() :
57
    error(QSystemSemaphore::NoError)
58
{
59
}
60
61
void QSystemSemaphorePrivate::setErrorString(const QString &function, int err)
62
{
63
    if (err == KErrNone)
64
        return;
65
66
    switch(err){
67
    case KErrAlreadyExists:
68
        errorString = QCoreApplication::tr("%1: already exists", "QSystemSemaphore").arg(function);
69
        error = QSystemSemaphore::AlreadyExists;
70
        break;
71
    case KErrNotFound:
72
        errorString = QCoreApplication::tr("%1: does not exist", "QSystemSemaphore").arg(function);
73
        error = QSystemSemaphore::NotFound;
74
        break;
75
    case KErrNoMemory:
76
    case KErrInUse:
77
        errorString = QCoreApplication::tr("%1: out of resources", "QSystemSemaphore").arg(function);
78
        error = QSystemSemaphore::OutOfResources;
79
        break;
80
    case KErrPermissionDenied:
81
        errorString = QCoreApplication::tr("%1: permission denied", "QSystemSemaphore").arg(function);
82
        error = QSystemSemaphore::PermissionDenied;
83
        break;
84
    default:
85
        errorString = QCoreApplication::tr("%1: unknown error %2", "QSystemSemaphore").arg(function).arg(err);
86
        error = QSystemSemaphore::UnknownError;
87
#ifdef QSYSTEMSEMAPHORE_DEBUG
88
        qDebug() << errorString << "key" << key;
89
#endif
90
        break;
91
    }
92
}
93
94
int QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode)
95
{
96
    if (semaphore.Handle())
97
        return semaphore.Handle();
98
99
    // don't allow making handles on empty keys
100
    if (key.isEmpty())
101
        return 0;
102
103
    TPtrC name(qt_QString2TPtrC(fileName));
104
    int err = KErrAlreadyExists;
105
    int tryCount = 10;
106
    // Sort out race conditions by retrying several times until existing handle is acquired.
107
    // Sometimes opening can fail inexplicably with KErrPermissionDenied many times in a row.
108
    while (err != KErrNoMemory && err != KErrNone && tryCount-- >= 0) {
109
        err = semaphore.CreateGlobal(name, initialValue, EOwnerProcess);
110
        if (err != KErrNoMemory && err != KErrNone)
111
            err = semaphore.OpenGlobal(name, EOwnerProcess);
112
    }
113
    if (err) {
114
        setErrorString(QLatin1String("QSystemSemaphore::handle"), err);
115
        return 0;
116
    }
117
118
    return semaphore.Handle();
119
}
120
121
void QSystemSemaphorePrivate::cleanHandle()
122
{
123
    semaphore.Close();
124
}
125
126
bool QSystemSemaphorePrivate::modifySemaphore(int count)
127
{
128
    if (0 == handle())
129
        return false;
130
131
    if (count > 0)
132
        semaphore.Signal(count);
133
    else
134
        semaphore.Wait();
135
136
    return true;
137
}
138
139
QT_END_NAMESPACE
140
141
#endif // QT_NO_SYSTEMSEMAPHORE