Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
7bb1c9a1
Commit
7bb1c9a1
authored
Jan 19, 2002
by
Fred Drake
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove the unused & broken PyThread_*_sema() functions and related constants.
This closes SF patch #504215.
parent
72c3bf07
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
0 additions
and
557 deletions
+0
-557
Include/pythread.h
Include/pythread.h
+0
-7
Python/thread_beos.h
Python/thread_beos.h
+0
-70
Python/thread_cthread.h
Python/thread_cthread.h
+0
-46
Python/thread_foobar.h
Python/thread_foobar.h
+0
-34
Python/thread_lwp.h
Python/thread_lwp.h
+0
-31
Python/thread_nt.h
Python/thread_nt.h
+0
-53
Python/thread_os2.h
Python/thread_os2.h
+0
-27
Python/thread_pth.h
Python/thread_pth.h
+0
-87
Python/thread_pthread.h
Python/thread_pthread.h
+0
-98
Python/thread_sgi.h
Python/thread_sgi.h
+0
-44
Python/thread_solaris.h
Python/thread_solaris.h
+0
-60
No files found.
Include/pythread.h
View file @
7bb1c9a1
...
...
@@ -25,13 +25,6 @@ DL_IMPORT(int) PyThread_acquire_lock(PyThread_type_lock, int);
#define NOWAIT_LOCK 0
DL_IMPORT
(
void
)
PyThread_release_lock
(
PyThread_type_lock
);
DL_IMPORT
(
PyThread_type_sema
)
PyThread_allocate_sema
(
int
);
DL_IMPORT
(
void
)
PyThread_free_sema
(
PyThread_type_sema
);
DL_IMPORT
(
int
)
PyThread_down_sema
(
PyThread_type_sema
,
int
);
#define WAIT_SEMA 1
#define NOWAIT_SEMA 0
DL_IMPORT
(
void
)
PyThread_up_sema
(
PyThread_type_sema
);
#ifndef NO_EXIT_PROG
DL_IMPORT
(
void
)
PyThread_exit_prog
(
int
);
DL_IMPORT
(
void
)
PyThread__PyThread_exit_prog
(
int
);
...
...
Python/thread_beos.h
View file @
7bb1c9a1
...
...
@@ -285,73 +285,3 @@ void PyThread_release_lock( PyThread_type_lock lock )
return
;
}
}
/* ----------------------------------------------------------------------
* Semaphore support.
*
* Guido says not to implement this because it's not used anywhere;
* I'll do it anyway, you never know when it might be handy, and it's
* easy...
*/
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
sem_id
sema
;
dprintf
((
"PyThread_allocate_sema called
\n
"
));
sema
=
create_sem
(
value
,
"python semaphore"
);
if
(
sema
<
B_NO_ERROR
)
{
/* TODO: that's bad, raise an exception */
return
0
;
}
dprintf
((
"PyThread_allocate_sema() -> %p
\n
"
,
sema
));
return
(
PyThread_type_sema
)
sema
;
}
void
PyThread_free_sema
(
PyThread_type_sema
sema
)
{
status_t
retval
;
dprintf
((
"PyThread_free_sema(%p) called
\n
"
,
sema
));
retval
=
delete_sem
(
(
sem_id
)
sema
);
if
(
retval
!=
B_NO_ERROR
)
{
/* TODO: that's bad, raise an exception */
return
;
}
}
int
PyThread_down_sema
(
PyThread_type_sema
sema
,
int
waitflag
)
{
status_t
retval
;
dprintf
((
"PyThread_down_sema(%p, %d) called
\n
"
,
sema
,
waitflag
));
if
(
waitflag
)
{
retval
=
acquire_sem
(
(
sem_id
)
sema
);
}
else
{
retval
=
acquire_sem_etc
(
(
sem_id
)
sema
,
1
,
B_TIMEOUT
,
0
);
}
if
(
retval
!=
B_NO_ERROR
)
{
/* TODO: that's bad, raise an exception */
return
0
;
}
dprintf
((
"PyThread_down_sema(%p) return
\n
"
,
sema
));
return
-
1
;
}
void
PyThread_up_sema
(
PyThread_type_sema
sema
)
{
status_t
retval
;
dprintf
((
"PyThread_up_sema(%p)
\n
"
,
sema
));
retval
=
release_sem
(
(
sem_id
)
sema
);
if
(
retval
!=
B_NO_ERROR
)
{
/* TODO: that's bad, raise an exception */
return
;
}
}
Python/thread_cthread.h
View file @
7bb1c9a1
...
...
@@ -154,49 +154,3 @@ PyThread_release_lock(PyThread_type_lock lock)
dprintf
((
"PyThread_release_lock(%p) called
\n
"
,
lock
));
mutex_unlock
((
mutex_t
)
lock
);
}
/*
* Semaphore support.
*
* This implementation is ripped directly from the pthreads implementation.
* Which is to say that it is 100% non-functional at this time.
*
* Assuming the page is still up, documentation can be found at:
*
* http://www.doc.ic.ac.uk/~mac/manuals/solaris-manual-pages/solaris/usr/man/man2/_lwp_sema_wait.2.html
*
* Looking at the man page, it seems that one could easily implement a
* semaphore using a condition.
*
*/
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
char
*
sema
=
0
;
dprintf
((
"PyThread_allocate_sema called
\n
"
));
if
(
!
initialized
)
PyThread_init_thread
();
dprintf
((
"PyThread_allocate_sema() -> %p
\n
"
,
sema
));
return
(
PyThread_type_sema
)
sema
;
}
void
PyThread_free_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_free_sema(%p) called
\n
"
,
sema
));
}
int
PyThread_down_sema
(
PyThread_type_sema
sema
,
int
waitflag
)
{
dprintf
((
"PyThread_down_sema(%p, %d) called
\n
"
,
sema
,
waitflag
));
dprintf
((
"PyThread_down_sema(%p) return
\n
"
,
sema
));
return
-
1
;
}
void
PyThread_up_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_up_sema(%p)
\n
"
,
sema
));
}
Python/thread_foobar.h
View file @
7bb1c9a1
...
...
@@ -113,37 +113,3 @@ PyThread_release_lock(PyThread_type_lock lock)
{
dprintf
((
"PyThread_release_lock(%p) called
\n
"
,
lock
));
}
/*
* Semaphore support.
*/
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
dprintf
((
"PyThread_allocate_sema called
\n
"
));
if
(
!
initialized
)
PyThread_init_thread
();
dprintf
((
"PyThread_allocate_sema() -> %p
\n
"
,
sema
));
return
(
PyThread_type_sema
)
sema
;
}
void
PyThread_free_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_free_sema(%p) called
\n
"
,
sema
));
}
int
PyThread_down_sema
(
PyThread_type_sema
sema
,
int
waitflag
)
{
dprintf
((
"PyThread_down_sema(%p, %d) called
\n
"
,
sema
,
waitflag
));
dprintf
((
"PyThread_down_sema(%p) return
\n
"
,
sema
));
return
-
1
;
}
void
PyThread_up_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_up_sema(%p)
\n
"
,
sema
));
}
Python/thread_lwp.h
View file @
7bb1c9a1
...
...
@@ -147,34 +147,3 @@ void PyThread_release_lock(PyThread_type_lock lock)
cv_broadcast
(((
struct
lock
*
)
lock
)
->
lock_condvar
);
mon_exit
(((
struct
lock
*
)
lock
)
->
lock_monitor
);
}
/*
* Semaphore support.
*/
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
PyThread_type_sema
sema
=
0
;
dprintf
((
"PyThread_allocate_sema called
\n
"
));
if
(
!
initialized
)
PyThread_init_thread
();
dprintf
((
"PyThread_allocate_sema() -> %p
\n
"
,
sema
));
return
(
PyThread_type_sema
)
sema
;
}
void
PyThread_free_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_free_sema(%p) called
\n
"
,
sema
));
}
int
PyThread_down_sema
(
PyThread_type_sema
sema
,
int
waitflag
)
{
dprintf
((
"PyThread_down_sema(%p, %d) called
\n
"
,
sema
,
waitflag
));
dprintf
((
"PyThread_down_sema(%p) return
\n
"
,
sema
));
return
-
1
;
}
void
PyThread_up_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_up_sema(%p)
\n
"
,
sema
));
}
Python/thread_nt.h
View file @
7bb1c9a1
...
...
@@ -319,56 +319,3 @@ void PyThread_release_lock(PyThread_type_lock aLock)
if
(
!
(
aLock
&&
LeaveNonRecursiveMutex
((
PNRMUTEX
)
aLock
)))
dprintf
((
"%ld: Could not PyThread_release_lock(%p) error: %l
\n
"
,
PyThread_get_thread_ident
(),
aLock
,
GetLastError
()));
}
/*
* Semaphore support.
*/
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
HANDLE
aSemaphore
;
dprintf
((
"%ld: PyThread_allocate_sema called
\n
"
,
PyThread_get_thread_ident
()));
if
(
!
initialized
)
PyThread_init_thread
();
aSemaphore
=
CreateSemaphore
(
NULL
,
/* Security attributes */
value
,
/* Initial value */
INT_MAX
,
/* Maximum value */
NULL
);
/* Name of semaphore */
dprintf
((
"%ld: PyThread_allocate_sema() -> %p
\n
"
,
PyThread_get_thread_ident
(),
aSemaphore
));
return
(
PyThread_type_sema
)
aSemaphore
;
}
void
PyThread_free_sema
(
PyThread_type_sema
aSemaphore
)
{
dprintf
((
"%ld: PyThread_free_sema(%p) called
\n
"
,
PyThread_get_thread_ident
(),
aSemaphore
));
CloseHandle
((
HANDLE
)
aSemaphore
);
}
/*
XXX must do something about waitflag
*/
int
PyThread_down_sema
(
PyThread_type_sema
aSemaphore
,
int
waitflag
)
{
DWORD
waitResult
;
dprintf
((
"%ld: PyThread_down_sema(%p) called
\n
"
,
PyThread_get_thread_ident
(),
aSemaphore
));
waitResult
=
WaitForSingleObject
(
(
HANDLE
)
aSemaphore
,
INFINITE
);
dprintf
((
"%ld: PyThread_down_sema(%p) return: %l
\n
"
,
PyThread_get_thread_ident
(),
aSemaphore
,
waitResult
));
return
0
;
}
void
PyThread_up_sema
(
PyThread_type_sema
aSemaphore
)
{
ReleaseSemaphore
(
(
HANDLE
)
aSemaphore
,
/* Handle of semaphore */
1
,
/* increment count by one */
NULL
);
/* not interested in previous count */
dprintf
((
"%ld: PyThread_up_sema(%p)
\n
"
,
PyThread_get_thread_ident
(),
aSemaphore
));
}
Python/thread_os2.h
View file @
7bb1c9a1
...
...
@@ -209,30 +209,3 @@ void PyThread_release_lock(PyThread_type_lock aLock)
DosExitCritSec
();
}
/*
* Semaphore support.
*/
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
return
(
PyThread_type_sema
)
0
;
}
void
PyThread_free_sema
(
PyThread_type_sema
aSemaphore
)
{
}
int
PyThread_down_sema
(
PyThread_type_sema
aSemaphore
,
int
waitflag
)
{
return
-
1
;
}
void
PyThread_up_sema
(
PyThread_type_sema
aSemaphore
)
{
dprintf
((
"%ld: PyThread_up_sema(%p)
\n
"
,
PyThread_get_thread_ident
(),
aSemaphore
));
}
Python/thread_pth.h
View file @
7bb1c9a1
...
...
@@ -206,90 +206,3 @@ void PyThread_release_lock(PyThread_type_lock lock)
status
=
pth_cond_notify
(
&
thelock
->
lock_released
,
0
);
CHECK_STATUS
(
"pth_cond_notify"
);
}
/*
* Semaphore support.
*/
struct
semaphore
{
pth_mutex_t
mutex
;
pth_cond_t
cond
;
int
value
;
};
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
struct
semaphore
*
sema
;
int
status
,
error
=
0
;
dprintf
((
"PyThread_allocate_sema called
\n
"
));
if
(
!
initialized
)
PyThread_init_thread
();
sema
=
(
struct
semaphore
*
)
malloc
(
sizeof
(
struct
semaphore
));
if
(
sema
!=
NULL
)
{
sema
->
value
=
value
;
status
=
pth_mutex_init
(
&
sema
->
mutex
);
CHECK_STATUS
(
"pth_mutex_init"
);
status
=
pth_cond_init
(
&
sema
->
cond
);
CHECK_STATUS
(
"pth_mutex_init"
);
if
(
error
)
{
free
((
void
*
)
sema
);
sema
=
NULL
;
}
}
dprintf
((
"PyThread_allocate_sema() -> %p
\n
"
,
sema
));
return
(
PyThread_type_sema
)
sema
;
}
void
PyThread_free_sema
(
PyThread_type_sema
sema
)
{
struct
semaphore
*
thesema
=
(
struct
semaphore
*
)
sema
;
dprintf
((
"PyThread_free_sema(%p) called
\n
"
,
sema
));
free
((
void
*
)
thesema
);
}
int
PyThread_down_sema
(
PyThread_type_sema
sema
,
int
waitflag
)
{
int
status
,
error
=
0
,
success
;
struct
semaphore
*
thesema
=
(
struct
semaphore
*
)
sema
;
dprintf
((
"PyThread_down_sema(%p, %d) called
\n
"
,
sema
,
waitflag
));
status
=
pth_mutex_acquire
(
&
thesema
->
mutex
,
!
waitflag
,
NULL
);
CHECK_STATUS
(
"pth_mutex_acquire"
);
if
(
waitflag
)
{
while
(
!
error
&&
thesema
->
value
<=
0
)
{
status
=
pth_cond_await
(
&
thesema
->
cond
,
&
thesema
->
mutex
,
NULL
);
CHECK_STATUS
(
"pth_cond_await"
);
}
}
if
(
error
)
success
=
0
;
else
if
(
thesema
->
value
>
0
)
{
thesema
->
value
--
;
success
=
1
;
}
else
success
=
0
;
status
=
pth_mutex_release
(
&
thesema
->
mutex
);
CHECK_STATUS
(
"pth_mutex_release"
);
dprintf
((
"PyThread_down_sema(%p) return
\n
"
,
sema
));
return
success
;
}
void
PyThread_up_sema
(
PyThread_type_sema
sema
)
{
int
status
,
error
=
0
;
struct
semaphore
*
thesema
=
(
struct
semaphore
*
)
sema
;
dprintf
((
"PyThread_up_sema(%p)
\n
"
,
sema
));
status
=
pth_mutex_acquire
(
&
thesema
->
mutex
,
0
,
NULL
);
CHECK_STATUS
(
"pth_mutex_acquire"
);
thesema
->
value
++
;
status
=
pth_cond_notify
(
&
thesema
->
cond
,
1
);
CHECK_STATUS
(
"pth_cond_notify"
);
status
=
pth_mutex_release
(
&
thesema
->
mutex
);
CHECK_STATUS
(
"pth_mutex_release"
);
}
Python/thread_pthread.h
View file @
7bb1c9a1
...
...
@@ -405,101 +405,3 @@ PyThread_release_lock(PyThread_type_lock lock)
status
=
pthread_cond_signal
(
&
thelock
->
lock_released
);
CHECK_STATUS
(
"pthread_cond_signal"
);
}
/*
* Semaphore support.
*/
struct
semaphore
{
pthread_mutex_t
mutex
;
pthread_cond_t
cond
;
int
value
;
};
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
struct
semaphore
*
sema
;
int
status
,
error
=
0
;
dprintf
((
"PyThread_allocate_sema called
\n
"
));
if
(
!
initialized
)
PyThread_init_thread
();
sema
=
(
struct
semaphore
*
)
malloc
(
sizeof
(
struct
semaphore
));
if
(
sema
!=
NULL
)
{
sema
->
value
=
value
;
status
=
pthread_mutex_init
(
&
sema
->
mutex
,
pthread_mutexattr_default
);
CHECK_STATUS
(
"pthread_mutex_init"
);
status
=
pthread_cond_init
(
&
sema
->
cond
,
pthread_condattr_default
);
CHECK_STATUS
(
"pthread_cond_init"
);
if
(
error
)
{
free
((
void
*
)
sema
);
sema
=
NULL
;
}
}
dprintf
((
"PyThread_allocate_sema() -> %p
\n
"
,
sema
));
return
(
PyThread_type_sema
)
sema
;
}
void
PyThread_free_sema
(
PyThread_type_sema
sema
)
{
int
status
,
error
=
0
;
struct
semaphore
*
thesema
=
(
struct
semaphore
*
)
sema
;
dprintf
((
"PyThread_free_sema(%p) called
\n
"
,
sema
));
status
=
pthread_cond_destroy
(
&
thesema
->
cond
);
CHECK_STATUS
(
"pthread_cond_destroy"
);
status
=
pthread_mutex_destroy
(
&
thesema
->
mutex
);
CHECK_STATUS
(
"pthread_mutex_destroy"
);
free
((
void
*
)
thesema
);
}
int
PyThread_down_sema
(
PyThread_type_sema
sema
,
int
waitflag
)
{
int
status
,
error
=
0
,
success
;
struct
semaphore
*
thesema
=
(
struct
semaphore
*
)
sema
;
dprintf
((
"PyThread_down_sema(%p, %d) called
\n
"
,
sema
,
waitflag
));
status
=
pthread_mutex_lock
(
&
thesema
->
mutex
);
CHECK_STATUS
(
"pthread_mutex_lock"
);
if
(
waitflag
)
{
while
(
!
error
&&
thesema
->
value
<=
0
)
{
status
=
pthread_cond_wait
(
&
thesema
->
cond
,
&
thesema
->
mutex
);
CHECK_STATUS
(
"pthread_cond_wait"
);
}
}
if
(
error
)
success
=
0
;
else
if
(
thesema
->
value
>
0
)
{
thesema
->
value
--
;
success
=
1
;
}
else
success
=
0
;
status
=
pthread_mutex_unlock
(
&
thesema
->
mutex
);
CHECK_STATUS
(
"pthread_mutex_unlock"
);
dprintf
((
"PyThread_down_sema(%p) return
\n
"
,
sema
));
return
success
;
}
void
PyThread_up_sema
(
PyThread_type_sema
sema
)
{
int
status
,
error
=
0
;
struct
semaphore
*
thesema
=
(
struct
semaphore
*
)
sema
;
dprintf
((
"PyThread_up_sema(%p)
\n
"
,
sema
));
status
=
pthread_mutex_lock
(
&
thesema
->
mutex
);
CHECK_STATUS
(
"pthread_mutex_lock"
);
thesema
->
value
++
;
status
=
pthread_cond_signal
(
&
thesema
->
cond
);
CHECK_STATUS
(
"pthread_cond_signal"
);
status
=
pthread_mutex_unlock
(
&
thesema
->
mutex
);
CHECK_STATUS
(
"pthread_mutex_unlock"
);
}
Python/thread_sgi.h
View file @
7bb1c9a1
...
...
@@ -378,50 +378,6 @@ void PyThread_release_lock(PyThread_type_lock lock)
perror
(
"usunsetlock"
);
}
/*
* Semaphore support.
*/
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
usema_t
*
sema
;
dprintf
((
"PyThread_allocate_sema called
\n
"
));
if
(
!
initialized
)
PyThread_init_thread
();
if
((
sema
=
usnewsema
(
shared_arena
,
value
))
==
NULL
)
perror
(
"usnewsema"
);
dprintf
((
"PyThread_allocate_sema() -> %p
\n
"
,
sema
));
return
(
PyThread_type_sema
)
sema
;
}
void
PyThread_free_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_free_sema(%p) called
\n
"
,
sema
));
usfreesema
((
usema_t
*
)
sema
,
shared_arena
);
}
int
PyThread_down_sema
(
PyThread_type_sema
sema
,
int
waitflag
)
{
int
success
;
dprintf
((
"PyThread_down_sema(%p) called
\n
"
,
sema
));
if
(
waitflag
)
success
=
uspsema
((
usema_t
*
)
sema
);
else
success
=
uscpsema
((
usema_t
*
)
sema
);
if
(
success
<
0
)
perror
(
waitflag
?
"uspsema"
:
"uscpsema"
);
dprintf
((
"PyThread_down_sema(%p) return
\n
"
,
sema
));
return
success
;
}
void
PyThread_up_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_up_sema(%p)
\n
"
,
sema
));
if
(
usvsema
((
usema_t
*
)
sema
)
<
0
)
perror
(
"usvsema"
);
}
/*
* Per-thread data ("key") support.
*/
...
...
Python/thread_solaris.h
View file @
7bb1c9a1
...
...
@@ -174,63 +174,3 @@ PyThread_release_lock(PyThread_type_lock lock)
if
(
mutex_unlock
((
mutex_t
*
)
lock
))
perror
(
"mutex_unlock"
);
}
/*
* Semaphore support.
*/
PyThread_type_sema
PyThread_allocate_sema
(
int
value
)
{
sema_t
*
sema
;
dprintf
((
"PyThread_allocate_sema called
\n
"
));
if
(
!
initialized
)
PyThread_init_thread
();
sema
=
(
sema_t
*
)
malloc
(
sizeof
(
sema_t
));
if
(
sema_init
(
sema
,
value
,
USYNC_THREAD
,
0
))
{
perror
(
"sema_init"
);
free
((
void
*
)
sema
);
sema
=
0
;
}
dprintf
((
"PyThread_allocate_sema() -> %p
\n
"
,
sema
));
return
(
PyThread_type_sema
)
sema
;
}
void
PyThread_free_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_free_sema(%p) called
\n
"
,
sema
));
if
(
sema_destroy
((
sema_t
*
)
sema
))
perror
(
"sema_destroy"
);
free
((
void
*
)
sema
);
}
int
PyThread_down_sema
(
PyThread_type_sema
sema
,
int
waitflag
)
{
int
success
;
dprintf
((
"PyThread_down_sema(%p) called
\n
"
,
sema
));
if
(
waitflag
)
success
=
sema_wait
((
sema_t
*
)
sema
);
else
success
=
sema_trywait
((
sema_t
*
)
sema
);
if
(
success
<
0
)
{
if
(
errno
==
EBUSY
)
success
=
0
;
else
perror
(
"sema_wait"
);
}
else
success
=
!
success
;
dprintf
((
"PyThread_down_sema(%p) return %d
\n
"
,
sema
,
success
));
return
success
;
}
void
PyThread_up_sema
(
PyThread_type_sema
sema
)
{
dprintf
((
"PyThread_up_sema(%p)
\n
"
,
sema
));
if
(
sema_post
((
sema_t
*
)
sema
))
perror
(
"sema_post"
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment