Merge "Allow reregistering callback"

This commit is contained in:
TreeHugger Robot 2017-02-24 20:21:24 +00:00 committed by Android (Google) Code Review
commit 6bce6f299d
2 changed files with 48 additions and 6 deletions

View file

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
#include <dirent.h>
#include <iostream>
#include <fstream>
@ -34,6 +35,9 @@ namespace usb {
namespace V1_0 {
namespace implementation {
// Set by the signal handler to destroy the thread
volatile bool destroyThread;
int32_t readFile(std::string filename, std::string& contents) {
std::ifstream file(filename);
@ -374,7 +378,7 @@ void* work(void* param) {
goto error;
}
while (1) {
while (!destroyThread) {
struct epoll_event events[64];
nevents = epoll_wait(epoll_fd, events, 64, -1);
@ -392,6 +396,7 @@ void* work(void* param) {
}
}
ALOGI("exiting worker thread");
error:
close(uevent_fd);
@ -401,26 +406,61 @@ error:
return NULL;
}
void sighandler(int sig)
{
if (sig == SIGUSR1) {
destroyThread = true;
ALOGI("destroy set");
return;
}
signal(SIGUSR1, sighandler);
}
Return<void> Usb::setCallback(const sp<IUsbCallback>& callback) {
if (mCallback != NULL) {
ALOGE("Callback already registered");
pthread_mutex_lock(&mLock);
if ((mCallback == NULL && callback == NULL) ||
(mCallback != NULL && callback != NULL)) {
mCallback = callback;
pthread_mutex_unlock(&mLock);
return Void();
}
mCallback = callback;
ALOGI("registering callback");
if (pthread_create(&mPoll, NULL, work, this)) {
ALOGE("pthread creation failed %d", errno);
mCallback = NULL;
if (mCallback == NULL) {
if (!pthread_kill(mPoll, SIGUSR1)) {
pthread_join(mPoll, NULL);
ALOGI("pthread destroyed");
}
pthread_mutex_unlock(&mLock);
return Void();
}
destroyThread = false;
signal(SIGUSR1, sighandler);
if (pthread_create(&mPoll, NULL, work, this)) {
ALOGE("pthread creation failed %d", errno);
mCallback = NULL;
}
pthread_mutex_unlock(&mLock);
return Void();
}
// Protects *usb assignment
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
Usb *usb;
Usb::Usb() {
pthread_mutex_lock(&lock);
// Make this a singleton class
assert(usb == NULL);
usb = this;
pthread_mutex_unlock(&lock);
}
} // namespace implementation
} // namespace V1_0
} // namespace usb

View file

@ -32,6 +32,7 @@ using ::android::hardware::Void;
using ::android::sp;
struct Usb : public IUsb {
Usb();
Return<void> switchRole(const hidl_string& portName, const PortRole& role) override;
Return<void> setCallback(const sp<IUsbCallback>& callback) override;
Return<void> queryPortStatus() override;
@ -39,6 +40,7 @@ struct Usb : public IUsb {
sp<IUsbCallback> mCallback;
private:
pthread_t mPoll;
pthread_mutex_t mLock = PTHREAD_MUTEX_INITIALIZER;
};
} // namespace implementation