Files
libreoffice/cppu/inc/uno/threadpool.h

184 lines
6.6 KiB
C
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2012-06-13 14:17:57 +01:00
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
2000-09-18 14:29:57 +00:00
2011-12-18 04:56:57 +01:00
#include <cppu/cppudllapi.h>
2000-09-18 14:29:57 +00:00
#include <rtl/byteseq.h>
#ifdef __cplusplus
extern "C" {
#endif
/***
* Thread identifier administration.
***/
/**
2001-10-29 11:16:42 +00:00
Establishs an association between the current thread and the given thread identifier.
There can be only one association at a time. The association must be broken by
2001-10-29 11:16:42 +00:00
uno_releaseIdFromCurrentThread().
This method is in general called by a bridge, that wants to bind a remote threadId
to a new thread.
@param pThreadId a byte sequence, that contains the identifier of the current thread.
2001-10-29 11:16:42 +00:00
@return true, when the identifier was registered.
false, when the thread has already an identifier. The identifier was not
2001-10-29 11:16:42 +00:00
altered. ( This is in general a bug ).
@see uno_releaseIdFromCurrentThread()
*/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC sal_Bool SAL_CALL uno_bindIdToCurrentThread( sal_Sequence *pThreadId )
2001-03-09 11:10:57 +00:00
SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
/**
Get the identifier of the current thread.
If no id has been bound for the thread before, a new one is generated and bound
to the thread.
2001-10-29 11:16:42 +00:00
For each call to uno_getIdOfCurrentThread(), a call to uno_releaseIdFromCurrentThread()
must be done.
@param ppThreadId [out] Contains the (acquired) ThreadId.
2001-10-29 11:16:42 +00:00
@see uno_releaseIdFromCurrentThread()
*/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC void SAL_CALL uno_getIdOfCurrentThread( sal_Sequence **ppThreadId )
2001-03-09 11:10:57 +00:00
SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
/**
If the internal refcount drops to zero, the association betwen threadId and
thread is broken.
*/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC void SAL_CALL uno_releaseIdFromCurrentThread()
2001-03-09 11:10:57 +00:00
SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
struct _uno_ThreadPool;
typedef struct _uno_ThreadPool * uno_ThreadPool;
2000-09-18 14:29:57 +00:00
/**
Creates a threadpool handle. Typically each remote bridge instances creates one
handle.
*/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC uno_ThreadPool SAL_CALL
uno_threadpool_create() SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
/**
Makes the current thread known to the threadpool. This function must be
called, BEFORE uno_threadpool_enter() is called and BEFORE a job for this
thread is put into the threadpool (avoid a race between this thread and
an incoming request/reply).
For every call to uno_threadpool_attach, a corrosponding call to
uno_threadpool_detach must be done.
@param hPool The bridge threadpool handle previously created by uno_threadpool_create.
*/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC void SAL_CALL
uno_threadpool_attach( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
/**
This method is called to wait for a reply of a previously sent request. This is a
blocking method. uno_threadpool_attach() must have been called before.
@param hPool the handle that was previously created by uno_threadpool_create().
@param ppJob [out] the pointer, that was given by uno_threadpool_putJob
2001-10-29 11:16:42 +00:00
0, when uno_threadpool_dispose() was the reason to fall off from threadpool.
@see uno_threadpool_dispose()
2000-09-18 14:29:57 +00:00
**/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC void SAL_CALL
uno_threadpool_enter( uno_ThreadPool hPool , void **ppJob )
2001-03-09 11:10:57 +00:00
SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
/**
Detaches the current thread from the threadpool. Must be called for
every call to uno_threadpool_attach.
*/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC void SAL_CALL
uno_threadpool_detach( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
/**
Puts a job into the pool. A job may eiter be a request or a reply
(replies have a 0 in the doRequest parameter). This function is non-blocking.
A request may either be synchronous or asynchronous.
If the request is synchronous, it is first looked up,
if there exists a handle with the given
identifier. If this is the case, the thread is woken up and the doRequest
function is called with the given pJob. If no handle exists,
a new thread is created and the given threadId is bound to the new thread.
If the request is asynchronous, it is put into the queue of asynchronous
requests for the current threadid. The requests are always executed in a new
thread, even if the thread with the given id is waiting in the pool. No id is bound
to the newly created thread. The responsibilty is left to the bridge ( if it
wishes to bind a name).
If pJob is a reply, there MUST be a thread with the given threadId waiting
for this reply.
@param pThreadId The Id of the thread, that initialized this request. (In general a
remote threadid).
@param pJob The argument, that doRequest will get or that will be returned by
uno_threadpool_enter().
@param doRequest The function, that shall be called to execute the request.
0 if pJob is a reply.
@param bIsOneway True, if the request is asynchrons. False, if it is synchronous.
Set to sal_False, if pJob is a reply.
*/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC void SAL_CALL
uno_threadpool_putJob(
uno_ThreadPool hPool,
sal_Sequence *pThreadId,
void *pJob,
void ( SAL_CALL * doRequest ) ( void *pThreadSpecificData ),
sal_Bool bIsOneway ) SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
/**
All threads, that are waiting on the hPool handle, are forced out of the pool.
The threads waiting with uno_threadpool_enter() will return with *ppJob == 0
Later calls to uno_threadpool_enter() using the hPool handle will also
return immeadiatly with *ppJob == 0.
@param hPool The handle to be disposed.
This function is called i.e. by a bridge, that is forced to dispose itself.
*/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC void SAL_CALL
uno_threadpool_dispose( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
/** Releases the previously with uno_threadpool_create() created handle.
The handle thus becomes invalid. It is an error to use the handle after
uno_threadpool_destroy().
Better fix for ThreadPool/ORequestThread life cycle This is a follow up to d015384e1d98fe77fd59339044f58efb1ab9fb25 "Fixed ThreadPool (and dependent ORequestThread) life cycle" that still had some problems: * First, if Bridge::terminate was first entered from the reader or writer thread, it would not join on that thread, so that thread could still be running during exit. That has been addressed by giving Bridge::dispose new semantics: It waits until both Bridge::terminate has completed (even if that was called from a different thread) and all spawned threads (reader, writer, ORequestThread workers) have been joined. (This implies that Bridge::dispose must not be called from such a thread, to avoid deadlock.) * Second, if Bridge::terminate was first entered from an ORequestThread, the call to uno_threadpool_dispose(0) to join on all such worker threads could deadlock. That has been addressed by making the last call to uno_threadpool_destroy wait to join on all worker threads, and by calling uno_threadpool_destroy only from the final Bridge::terminate (from Bridge::dispose), to avoid deadlock. (The special semantics of uno_threadpool_dispose(0) are no longer needed and have been removed, as they conflicted with the fix for the third problem below.) * Third, once uno_threadpool_destroy had called uno_threadpool_dispose(0), the ThreadAdmin singleton had been disposed, so no new remote bridges could successfully be created afterwards. That has been addressed by making ThreadAdmin a member of ThreadPool, and making (only) those uno_ThreadPool handles with overlapping life spans share one ThreadPool instance (which thus is no longer a singleton, either). Additionally, ORequestThread has been made more robust (in the style of salhelper::Thread) to avoid races. Change-Id: I2cbd1b3f9aecc1bf4649e482d2c22b33b471788f
2012-05-23 09:42:37 +02:00
A call to uno_threadpool_destroy can synchronously join on spawned worker
threads, so this function must never be called from such a worker thread.
2001-10-29 11:16:42 +00:00
@see uno_threadpool_create()
*/
2011-12-18 04:56:57 +01:00
CPPU_DLLPUBLIC void SAL_CALL
uno_threadpool_destroy( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C();
2000-09-18 14:29:57 +00:00
#ifdef __cplusplus
}
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */